<?php

namespace app\api\controller\v1;
include_once APP_PATH . 'api/common.php';

use app\common\controller\Api;
use think\Db;
use think\Env;
use app\common\library\OcationCoordinateHelper;

class Event extends Api
{
    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';
    public $notApplyed = false;

    // SQL调试信息存储
    private $sqlDebugInfo = null;

    public function _initialize()
    {
        // 添加调试日志
        error_log("Event控制器 _initialize 开始执行 - " . date('Y-m-d H:i:s'));

        try {
            parent::_initialize();
            error_log("Event控制器 _initialize 完成 - " . date('Y-m-d H:i:s'));
        } catch (\Exception $e) {
            error_log("Event控制器 _initialize 失败: " . $e->getMessage() . " - " . date('Y-m-d H:i:s'));
            throw $e;
        }
    }

    /**
     * 获取教学点经纬度和地址（带回退逻辑）
     * 使用统一的工具类处理
     *
     * @param int $ocationId 教学点ID
     * @return array ['longitude' => float, 'latitude' => float, 'address' => string] 或 ['longitude' => null, 'latitude' => null, 'address' => null]
     */
    public function getOcationCoordinates($ocationId)
    {
        return OcationCoordinateHelper::getSimpleCoordinates($ocationId);
    }

    /**
     * 批量获取多个教学点的经纬度和地址
     *
     * @param array $ocationIds 教学点ID数组
     * @return array 格式：[ocation_id => ['longitude' => float, 'latitude' => float, 'address' => string], ...]
     */
    public function getBatchOcationCoordinates($ocationIds)
    {
        $batchResult = OcationCoordinateHelper::getBatchCoordinates($ocationIds);

        // 转换为简化格式，保持向后兼容
        $result = [];
        foreach ($batchResult as $ocationId => $coordinates) {
            $result[$ocationId] = [
                'longitude' => $coordinates['longitude'],
                'latitude' => $coordinates['latitude'],
                'address' => $coordinates['address']
            ];
        }

        return $result;
    }

    /**
     * 获取教学点的完整位置信息（经纬度 + 地址）
     *
     * @param int $ocationId 教学点ID
     * @return array
     */
    public function getOcationLocationInfo()
    {
        $ocationId = $this->request->param('ocation_id', 0, 'intval');

        if (!$ocationId) {
            return json([
                'code' => 0,
                'msg' => '教学点ID不能为空',
                'data' => null
            ]);
        }

        try {
            // 使用工具类获取完整位置信息
            $locationInfo = OcationCoordinateHelper::getLocationInfo($ocationId);

            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => $locationInfo
            ]);

        } catch (\Exception $e) {
            return json([
                'code' => 0,
                'msg' => '获取位置信息失败：' . $e->getMessage(),
                'data' => null
            ]);
        }
    }

    /**
     * 批量获取多个教学点的位置信息
     *
     * @return array
     */
    public function getBatchOcationLocationInfo()
    {
        $ocationIds = $this->request->param('ocation_ids', '', 'trim');

        if (empty($ocationIds)) {
            return json([
                'code' => 0,
                'msg' => '教学点ID列表不能为空',
                'data' => null
            ]);
        }

        // 解析教学点ID列表
        if (is_string($ocationIds)) {
            $ocationIds = explode(',', $ocationIds);
        }

        $ocationIds = array_filter(array_map('intval', $ocationIds));

        if (empty($ocationIds)) {
            return json([
                'code' => 0,
                'msg' => '无效的教学点ID列表',
                'data' => null
            ]);
        }

        // 限制批量查询数量
        if (count($ocationIds) > 20) {
            return json([
                'code' => 0,
                'msg' => '批量查询数量不能超过20个',
                'data' => null
            ]);
        }

        try {
            // 使用工具类批量获取位置信息
            $locationInfos = OcationCoordinateHelper::getBatchLocationInfo($ocationIds);

            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => $locationInfos,
                'count' => count($locationInfos)
            ]);

        } catch (\Exception $e) {
            return json([
                'code' => 0,
                'msg' => '批量获取位置信息失败：' . $e->getMessage(),
                'data' => null
            ]);
        }
    }

    /**
     * 根据经纬度获取地址信息
     *
     * @return array
     */
    public function getAddressByCoordinates()
    {
        $longitude = $this->request->param('longitude', 0, 'floatval');
        $latitude = $this->request->param('latitude', 0, 'floatval');

        if (!$longitude || !$latitude) {
            return json([
                'code' => 0,
                'msg' => '经纬度参数不能为空',
                'data' => null
            ]);
        }

        try {
            // 使用工具类获取地址信息
            $addressResult = OcationCoordinateHelper::getAddressByCoordinates($longitude, $latitude);

            if ($addressResult['success']) {
                return json([
                    'code' => 1,
                    'msg' => $addressResult['message'],
                    'data' => $addressResult['data']
                ]);
            } else {
                return json([
                    'code' => 0,
                    'msg' => $addressResult['message'],
                    'data' => null
                ]);
            }

        } catch (\Exception $e) {
            return json([
                'code' => 0,
                'msg' => '获取地址信息失败：' . $e->getMessage(),
                'data' => null
            ]);
        }
    }


    /**
     * 基础课程查询方法 - 供getList和getCourseDetailsBySubject共同使用
     * @param array $params 查询参数
     * @return array
     */
    public function baseCourseQuery($params = [])
    {
        $user = $this->auth->getUser(true);
        $uid = $user['uid'] ?? 0;


        // 默认参数
        $defaults = [
            'page' => 1,
            'limit' => 1000,
            'latitude' => 22.81000000000000,
            'longitude' => 108.35528564453125,
            'school_id' => null,
            'level1' => null,
            'level2' => null,
            'keyword' => null,
            'subject_name' => null,
            'subjectlv_id' => null,
            'order' => null, // 默认为null，将使用地理位置排序
            'ocation_ids' => null, // 支持按教学点ID筛选
            'include_sub_ocations' => false, // 是否包含子教学点
            'time_filter' => null, // 时间筛选（recent-最近课程，upcoming-即将开始，ongoing-正在进行）
            'classes_type' => null, // 课程类型筛选（1-学校课程，2-社区课程）
            'community_id' => null, // 社区ID筛选
            'is_free' => null, // 是否免费筛选（1-免费，0-收费）
            'current_day' => $params['current_day'] ?? date("Y-m-d 00:00:00"), // 当前日期筛选
            'table_id' => null,
            'publicwelfare_id' => null,
            'q' => null, // 新增q参数用于课程名或班级名模糊匹配
            'sort_field' => null, // 新增sort_field参数用于自定义排序字段
            'sort_order' => 'asc', // 新增sort_order参数用于自定义排序方向
            // 新增多选参数默认值
            'school' => null, // 学校ID多选，格式：1,2,3
            'locations' => null, // 教学点ID多选，格式：1,2,3
            'orientation' => null, // 定位多选：1=免费,2=公益,3=普惠
            'description' => null, // 描述多选：1=名额有限,2=学分兑换
            'feature' => null, // 功能多选：1=预约,2=报名,3=收藏
            'classes' => null, // 班级多选：1=线上,2=线下
            'subjectLv' => null, // 学科级别多选
            'classesType' => null, // 课程类型多选
            'firstLevelManagements' => null, // 一级管理多选
            'secondLevelManagements' => null, // 二级管理多选
            'is_started' => null,
        ];

        $params = array_merge($defaults, $params);
        if ($params['current_day'] == "") {
            $params['current_day'] = date("Y-m-d 00:00:00");
        }
        // 确保经纬度参数有效
        $latitude = isset($params['latitude']) && $params['latitude'] != null && $params['latitude'] != '' && $params['latitude'] != 0 ? $params['latitude'] : 22.81000000000000;
        $longitude = isset($params['longitude']) && $params['longitude'] != null && $params['longitude'] != '' && $params['longitude'] != 0 ? $params['longitude'] : 108.35528564453125;

        $query = Db::name('course_table_autoplan')
            ->alias('t')
            ->join('eb_school sch', 'sch.id=t.school_id', 'LEFT')
            ->join('eb_classes c1', 't.table_type=1 AND c1.id=t.classes_id', 'LEFT')
            ->join('fa_ocation_class c3', 't.table_type=2 AND c3.id=t.classes_id', 'LEFT')
            ->join('fa_community_code_config c2', 't.table_type=2 AND c2.id=t.classes_id', 'LEFT')
            ->join('fa_community_course_config course2', 't.table_type=2 AND course2.id=t.subject_lv', 'LEFT')
            ->join('fa_course_table tb', 't.table_type=1 AND tb.id=t.table_id', 'LEFT')
            ->join('fa_community_publicwelfare tb2', 't.table_type=2 AND tb2.id=t.publicwelfare_id', 'LEFT')
            ->join('fa_ocation o', 'o.id=t.ocation_id', 'LEFT')
            ->join('fa_ocation o2', 'o.pid=o2.id', 'LEFT')
            ->join('fa_address_lv s', 't.table_type=1 AND s.id=c1.addresslv_id', 'LEFT')
            ->join('eb_apply_form_item a', "a.classes_id=t.classes_id AND a.classes_type=1 AND a.user_id='{$uid}' AND a.status=1", 'LEFT')
            ->join('eb_apply_form_item a2', "a2.classes_id=t.classes_id AND a2.classes_type=2 AND a2.user_id='{$uid}' AND a2.status=1", 'LEFT')
            ->join('eb_apply_form f', 't.table_type=1 AND f.id = t.apply_form_id', 'LEFT')
            ->join('eb_apply_form f2', 't.table_type=2 AND f2.id=a2.form_id', 'LEFT')
            ->join('fa_subject_lv sb', 't.table_type=1 AND sb.id=c1.subject_lv', 'LEFT')
            ->join('fa_order odr', 'odr.id=a.order_id', 'LEFT')
            ->join('fa_refund refund', 'refund.order_id=odr.id', 'LEFT')
            ->join('fa_course_table_classplant pl', 'pl.classes_id=c1.id', 'LEFT')
            ->join('fa_favorites fav', "fav.user_id='{$uid}' AND fav.school_id=t.school_id AND fav.type=2 AND fav.target_id=t.classes_id", 'LEFT');
            $query->join('fa_user u', "u.id={$uid}", 'LEFT')
                ->join('fa_registration reg', "reg.user_id='{$uid}' AND reg.table_id=t.table_id", 'LEFT')
                ->join("(SELECT classes_id, table_type, MIN(STR_TO_DATE(CONCAT(date,' ', start_time), '%Y-%m-%d %H:%i')) AS min_start_dt FROM fa_course_table_autoplan WHERE status=1 GROUP BY classes_id, table_type) tmin", "tmin.classes_id=t.classes_id AND tmin.table_type=t.table_type", "LEFT");
        $fields = [
            'DISTINCT t.id as t_id',
            't.classes_id as classes_id',
            't.table_type as classes_type',
            'COALESCE(a.id,a2.id)>0 as is_applyed',
            'a.id as a_apply_id',
            'a2.id as a2_apply_id',
            'COALESCE(a.id,a2.id) as apply_id',
            'COALESCE(a.order_id,a2.order_id) as order_id',
            'COALESCE(a.pay_status,a2.pay_status) as pay_status',
            'odr.amount as order_amount',
            'odr.order_sn as order_sn',
            'odr.payment_status',
            'odr.refund_status',
            'refund.refund_fee',
            'refund.update_time as refund_time',
            't.table_type',
            't.school_id',
            'sch.name as schoolName',
            "CASE WHEN t.table_type = 1 THEN t.classes_id ELSE CONCAT('c', t.id) END as classes",
            "COALESCE(c1.name, CONCAT(o.name,course2.name,'课堂')) as className",
            'COALESCE(c1.subject_lv, t.subject_lv) as subject_id',
            'o.rel_type',
            'o.address_lv_octionlevel',
            'tmin.min_start_dt as start_date',
            'COALESCE(CONCAT(t.date,\' \', t.end_time),tb.end_date) as end_date',
            'COALESCE(f.id,f2.id) as apply_form_id',
            'COALESCE(f.apply_type,f2.apply_type) as apply_type',
            'COALESCE(f.course_type,f2.course_type) as course_type',
            'o.id as ocation_id',
            'COALESCE(f.enable_registration_conditions,f2.enable_registration_conditions) as enable_registration_conditions',
            'COALESCE(f.male_age_min,f2.male_age_min) as male_age_min',
            'COALESCE(f.male_age_max,f2.male_age_max) as male_age_max',
            'COALESCE(f.female_age_min,f2.female_age_min) as female_age_min',
            'COALESCE(f.female_age_max,f2.female_age_max) as female_age_max',
            'COALESCE(f.other_conditions,f2.other_conditions) as other_conditions',
            'COALESCE(f.enable_terms_agreement,f2.enable_terms_agreement) as enable_terms_agreement',
            'COALESCE(f.terms_title,f2.terms_title) as terms_title',
            'COALESCE(f.terms_content,f2.terms_content) as terms_content',
            'COALESCE(f.is_staged,f2.is_staged) as is_staged',
            'COALESCE(f.staged_name,f2.staged_name) as staged_name',
            'COALESCE(f.stage1_start_time,f2.stage1_start_time) as stage1_start_time',
            'COALESCE(f.stage1_end_time,f2.stage1_end_time) as stage1_end_time',
            'COALESCE(f.stage1_target,f2.stage1_target) as stage1_target',
            'COALESCE(f.stage2_start_time,f2.stage2_start_time) as stage2_start_time',
            'COALESCE(f.stage2_end_time,f2.stage2_end_time) as stage2_end_time',
            'COALESCE(f.stage2_target,f2.stage2_target) as stage2_target',
            'COALESCE(f.stage_config,f2.stage_config) as stage_config',
            'COALESCE(f.enable_registration_form,f2.enable_registration_form) as enable_registration_form',
            'COALESCE(f.form_title,f2.form_title) as form_title',
            'COALESCE(f.form_description,f2.form_description) as form_description',
            'COALESCE(f.required_fields,f2.required_fields) as required_fields',
            'COALESCE(f.enable_signature_pad,f2.enable_signature_pad) as enable_signature_pad',
            'COALESCE(f.enable_matters_setting,f2.enable_matters_setting) as enable_matters_setting',
            'COALESCE(f.enable_offline_registration,f2.enable_offline_registration) as enable_offline_registration',
            'COALESCE(f.enable_quantity_limit,f2.enable_quantity_limit) as enable_quantity_limit',
            'COALESCE(f.max_courses_per_person,f2.max_courses_per_person) as max_courses_per_person',
            'CONCAT(o2.name, o.name) as ocation_name',
            'o.name as ocation_name2',
            'CONCAT(o2.name, o.name) as parent_teaching_ocation_name',
            't.parent_teaching_ocation_id',
            't.top_teaching_ocation_id',
            'COALESCE(f.is_use_integral,f2.is_use_integral) as is_use_integral',
            "COALESCE(course2.cover,c1.cover,'/uploads/20250304/52f6eb9ff9b883bd956a5cb58f5e5254_220_220.png') as cover",
            'course2.cover as course_cover',
            'COALESCE(sb.name, course2.name) as subject',
            'course2.header_image as header_image_community',
            'COALESCE(c1.header_image, course2.header_image) as header_image',
            'COALESCE(c1.price, 0) as price',
            't.table_id',
            't.school_id',
            't.community_id',
            't.is_free',
            't.publicwelfare_id',
            'COALESCE(o.longitude, o2.longitude) as zlongitude',
            'COALESCE(o.latitude, o2.latitude) as zlatitude',
            'tb.name as course_name',
            'o2.name as location_name',
            'c1.intro as description',
            'o.address as address',
            'c1.description as detail_description',
            'o.longitude',
            'o.latitude',
            'c1.name as classes_name',
            'c1.header_image as header_image_class',
            'c1.image',
            'sb.id as class_id',
            'sb.name as subject_name',
            'sb.id as subjectlv_id',
            't.date',
            't.start_time as start_time',
            't.end_time as end_time',
            'f.is_close',
            'f.is_end',
            'f.is_finished',
            'fav.id as is_favorite',
            'CONCAT(t.date, \' \', t.start_time, \':00\') as full_start_time',
            '(c1.num - COALESCE(c1.apply_num, 0)) as remaining_slots',
            'tb.start_date as table_start_date',
            'pl.ocourse_count',
            '(NOW() > (SELECT MIN(CONCAT(t2.date,\' \', t2.start_time, \':00\')) FROM fa_course_table_autoplan t2 WHERE t2.status=1 AND t2.classes_id=t.classes_id AND t2.table_type=t.table_type)) as is_started',
            'c1.num',
            'c1.apply_num',
            "(6371 * ACOS(
        COS(RADIANS({$latitude})) *
        COS(RADIANS(COALESCE(o.latitude, o2.latitude))) *
        COS(RADIANS(COALESCE(o.longitude, o2.longitude)) - RADIANS({$longitude})) +
        SIN(RADIANS({$latitude})) *
        SIN(RADIANS(COALESCE(o.latitude, o2.latitude)))
    )) AS km,f.special_channel_phones,f.special_channel_classes,u.mobile,reg.phone,t.apply_form_id ,c1.status,f.start_time AS apply_start_date,f.end_time AS apply_end_date"
        ];

        $query = $query->field($fields)
            ->where('t.status', 1)
            ->where(function ($query) {
                $query->where('c1.status', 1)->whereOr('c3.status', 1);
            });

        // 特殊渠道条件（仅在用户登录时应用）
        if (isset($uid) && $uid > 0) {
            $query->where(function ($query) use ($uid,$params) {
                if(isset($_REQUEST['table_id']) && $_REQUEST['table_id'] > 0) {
                                $query->whereRaw("(
                        (
                            (f.special_channel_classes IS NOT NULL AND f.special_channel_classes <> '')
                            AND FIND_IN_SET(c1.id, REPLACE(REPLACE(REPLACE(COALESCE(f.special_channel_classes, ''), ' ', ','), '\r', ','), '\n', ',')) > 0
                            AND (
                                FIND_IN_SET(u.mobile, REPLACE(REPLACE(REPLACE(COALESCE(f.special_channel_phones, ''), ' ', ','), '\r', ','), '\n', ',')) > 0
                                OR FIND_IN_SET(reg.phone, REPLACE(REPLACE(REPLACE(COALESCE(f.special_channel_phones, ''), ' ', ','), '\r', ','), '\n', ',')) > 0
                            )
                        ))");


                }else{
                        $now = time();
                        $tablesql = '';
                        if ($params['table_id'] !== null) {
                            $tablesql = " AND `t`.`table_id` = " . intval($params['table_id']);
                        }

                        $query->whereRaw("
                        (
                            (
                                (f.special_channel_classes IS NOT NULL AND f.special_channel_classes <> '')
                                AND FIND_IN_SET(c1.id, REPLACE(REPLACE(REPLACE(COALESCE(f.special_channel_classes, ''), ' ', ','), '\r', ','), '\n', ',')) > 0
                                AND (
                                    FIND_IN_SET(u.mobile, REPLACE(REPLACE(REPLACE(COALESCE(f.special_channel_phones, ''), ' ', ','), '\r', ','), '\n', ',')) > 0
                                    OR FIND_IN_SET(reg.phone, REPLACE(REPLACE(REPLACE(COALESCE(f.special_channel_phones, ''), ' ', ','), '\r', ','), '\n', ',')) > 0
                                )
                            )
                            OR (
                                (f.special_channel_classes IS NULL OR f.special_channel_classes = '')
                                AND UNIX_TIMESTAMP(STR_TO_DATE(CONCAT(t.date,' ', t.start_time), '%Y-%m-%d %H:%i')) >= {$now}
                                {$tablesql}
                            )
                        )
                        ");
                }
            });
            $query->group('t.classes_id');
        } elseif($params['table_id'] !== null) {
            // 未登录用户：只能访问无特殊渠道限制的课程
            $query->where('(NOW() < (SELECT MIN(CONCAT(t2.date,\' \', t2.start_time, \':00\')) FROM fa_course_table_autoplan t2 WHERE t2.status=1 AND t2.classes_id=t.classes_id AND t2.table_type=t.table_type))', '0');
            $query->where('t.table_id',  $params['table_id']);
            $query->where('f.start_time', '<=', date('Y-m-d H:i:s', time()));
            $query->where('f.end_time', '>=', date('Y-m-d H:i:s', time()));
            $query->where('f.is_end', '=', 0);
            $query->where('f.is_finished', '=', 0);
            $query->where('f.is_close', '=', 0);
            $query->group('t.classes_id');
        }

        // 添加筛选条件
        if ($params['school_id']) {
            $query->where('sch.id', $params['school_id']);
        }
        if ($params['level1']) {
            $query->where('sb.id', $params['level1']);
        }
        if (isset($params['first_level_management']) && $params['first_level_management']) {
            $query->where('sb.id', $params['first_level_management']);
        }
        if (isset($params['second_level_management']) && $params['second_level_management']) {
            $query->where('sb.id', $params['second_level_management']);
        }
        if ($params['level2']) {
            $query->where('sb.id', $params['level2']);
        }
        if ($params['keyword']) {
            $query->where('c1.name|c1.intro|c1.labels|tb.name', 'like', "%{$params['keyword']}%");
        }
        if ($params['is_started'] === 0) {
            $query->whereRaw("NOW() > (SELECT MIN(CONCAT(t2.date,' ', t2.start_time, ':00')) FROM fa_course_table_autoplan t2 WHERE t2.status=1 AND t2.classes_id=t.classes_id AND t2.table_type=t.table_type)");
        } elseif ($params['is_started'] === 1) {
            $query->whereRaw("NOW() <= (SELECT MIN(CONCAT(t2.date,' ', t2.start_time, ':00')) FROM fa_course_table_autoplan t2 WHERE t2.status=1 AND t2.classes_id=t.classes_id AND t2.table_type=t.table_type)");
        }

        if ($params['q']) {
            // 新增q参数，用于课程名或班级名模糊匹配
            $query->where(function ($query) use ($params) {
                $query->where('tb.name', 'like', "%{$params['q']}%") // 课程名
                ->whereOr('c1.name', 'like', "%{$params['q']}%") // 班级名
                ->whereOr('c3.name', 'like', "%{$params['q']}%") // 班级名
                ->whereOr('sb.name', 'like', "%{$params['q']}%") // 学科名
                ->whereOr('course2.name', 'like', "%{$params['q']}%") // 社区课程名
                ->whereOr('o.address', 'like', "%{$params['q']}%"); // 教学点名
            });
        }
        if ($params['subject_name']) {
            $query->where('sb.name', $params['subject_name']);
        }
        if ($params['subjectlv_id']) {
            $query->where('sb.id', $params['subjectlv_id']);
        }
        if (!$this->notApplyed) {
            //$query->where('a.id','>',0);
        }

        // 新增：按教学点ID筛选
        $ocation_ids = $this->getAllSubOcationIds($params['ocation_ids']);
        if ($ocation_ids) {
            if (is_array($ocation_ids)) {
                $query->where('t.ocation_id', 'in', $ocation_ids);
            } else {
                $query->where('t.ocation_id', $ocation_ids);
            }
        }

        // 时间筛选
        if ($params['time_filter']) {
            $currentTime = time();
            switch ($params['time_filter']) {
                case 'recent':
                    // 最近课程：包括1小时内结束的课程
                    $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.end_time, ':00'))", '>=', $currentTime - 3600);
                    break;
                case 'upcoming':
                    // 即将开始：未来的课程
                    $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '>', $currentTime);
                    break;
                case 'ongoing':
                    // 正在进行：当前时间在开始和结束时间之间
                    $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '<=', $currentTime)
                        ->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.end_time, ':00'))", '>=', $currentTime);
                    break;
                case 'today':
                    // 今日课程
                    $query->where('t.date', date('Y-m-d'));
                    break;
            }
        }

        // 课程类型筛选
        if ($params['classes_type'] !== null) {
            $query->where('t.table_type', $params['classes_type']);
        }


        if ($params['publicwelfare_id'] !== null) {
            $query->where('t.publicwelfare_id', $params['publicwelfare_id']);
        }

        // 社区ID筛选
        if ($params['community_id']) {
            // 通过教学点的community_id字段筛选
            $query->join('fa_ocation oc_filter', 'oc_filter.id = t.ocation_id', 'INNER')
                ->where('oc_filter.community_id', $params['community_id']);
        }

        // 是否免费筛选
        if ($params['is_free'] !== null) {
            if ($params['is_free'] == 1) {
                // 免费课程：价格为0或null
                $query->where(function ($query) {
                    $query->whereNull('c1.price')
                        ->whereOr('c1.price', 0);
                });
            } else {
                // 收费课程：价格大于0
                $query->where('c1.price', '>', 0);
            }
        }

        // 新增：按学校ID筛选（多选）
        if ($params['school']) {
            $schoolIds = explode(',', $params['school']);
            $query->where('t.school_id', 'in', $schoolIds);
        }

        // 新增：按教学点ID筛选（多选）
        if ($params['locations']) {
            $locationIds = explode(',', $params['locations']);
            $locationIds = $this->getAllSubOcationIds($locationIds);
            $query->where('t.ocation_id', 'in', $locationIds);
        }

        // 新增：按课堂类型筛选（多选：1=社区课程,2=班级课程,3=公开课）
        if ($params['classes_type']) {
            $classesTypeIds = explode(',', $params['classes_type']);
            $query->where('t.table_type', 'in', $classesTypeIds);
        }

        // 新增：按课程类型筛选(suject_lv_id)（多选）
        if ($params['subjectlv_id']) {
            $subjectLvIds = explode(',', $params['subjectlv_id']);
            $query->where('sb.id', 'in', $subjectLvIds);
        }

        if ($params['subjectLv']) {
            $subjectLvIds = explode(',', $params['subjectLv']);
            $query->where('sb.id', 'in', $subjectLvIds);
        }

        if ($params['classesType']) {
            $classesTypeIds = explode(',', $params['classesType']);
            $query->where('t.table_type', 'in', $classesTypeIds);
        }

        if ($params['firstLevelManagements']) {
            $firstLevelManagementsIds = explode(',', $params['firstLevelManagements']);
            $query->where('o.id', 'in', $firstLevelManagementsIds);
        }

        if ($params['secondLevelManagements']) {
            $secondLevelManagementsIds = explode(',', $params['secondLevelManagements']);
            $query->where('o.id', 'in', $secondLevelManagementsIds);
        }


        // 新增：按定位筛选（多选：1=免费,2=公益,3=普惠）
        if ($params['orientation']) {
            $orientationIds = explode(',', $params['orientation']);
            $query->where(function ($query) use ($orientationIds) {
                foreach ($orientationIds as $id) {
                    switch ($id) {
                        case '1': // 免费
                            $query->whereOr(function ($query) {
                                $query->whereNull('c1.price')
                                    ->whereOr('c1.price', 0);
                            });
                            break;
                        case '2': // 公益
                            $query->whereOr('t.publicwelfare_id', '>', 0);
                            break;
                        case '3': // 普惠
                            $query->whereOr('c1.price', '>', 0)
                                ->where('c1.price', '<', 100); // 假设价格小于100为普惠
                            break;
                    }
                }
            });
        }

        // 新增：按描述筛选（多选：1=名额有限,2=学分兑换）
        if ($params['description']) {
            $descriptionIds = explode(',', $params['description']);
            $query->where(function ($query) use ($descriptionIds) {
                foreach ($descriptionIds as $id) {
                    switch ($id) {
                        case '1': // 名额有限
                            $query->whereOr('c1.num', '>', 0);
                            break;
                        case '2': // 学分兑换
                            $query->whereOr('f.is_use_integral', 1)
                                ->whereOr('f2.is_use_integral', 1);
                            break;
                    }
                }
            });
        }

        // 新增：按功能筛选（多选：1=预约,2=报名,3=收藏）
        if ($params['feature']) {
            $featureIds = explode(',', $params['feature']);
            $query->where(function ($query) use ($featureIds) {
                foreach ($featureIds as $id) {
                    switch ($id) {
                        case '1': // 预约
                            $query->whereOr('t.apply_type', 0);
                            break;
                        case '2': // 报名
                            $query->whereOr('t.apply_type', 1);
                            break;
                        case '3': // 收藏
                            $query->whereOr('fav.id', ">", 0);
                            break;
                    }
                }
            });
        }
        $kmExpr = "(6371 * ACOS(COS(RADIANS({$latitude})) * COS(RADIANS(COALESCE(o.latitude, o2.latitude))) * COS(RADIANS(COALESCE(o.longitude, o2.longitude)) - RADIANS({$longitude})) + SIN(RADIANS({$latitude})) * SIN(RADIANS(COALESCE(o.latitude, o2.latitude)))))";
        $startExprPlain = "STR_TO_DATE(CONCAT(t.date,' ', t.start_time), '%Y-%m-%d %H:%i')";
        $startExprJoin  = "tmin.min_start_dt";

        // 如果有自定义排序字段，使用自定义排序
        if ($params['sort_field']) {
            $orderBy = $params['sort_field'] . ' ' . $params['sort_order'];
        } // 否则使用传入的order参数
        else if ($params['order']) {
            $orderBy = $params['order'];
        }

        // 当有q参数、按价格排序或table_id>0时，按班级ID分组合并课程
        // 检查是否按价格排序（支持sort_field参数和order参数两种方式）
        $isPriceSorting = ($params['sort_field'] == 'price') ||
            (isset($params['order']) && strpos($params['order'], 'price') !== false);

        $shouldGroup = $params['q'] || $params['classesType'] || $params['subjectLv'] || $params['firstLevelManagements'] || $params['secondLevelManagements'] || $params['orientation'] || $params['description'] || $params['feature'] || $isPriceSorting || ($params['table_id'] && $params['table_id'] > 0);

        if ($shouldGroup) {
            $orderBy = $startExprJoin . " ASC, " . $kmExpr . " ASC";
        } else {
            $orderBy = $startExprPlain . " ASC, " . $kmExpr . " ASC";
        }

        // 自定义排序字段处理（不使用子查询）
        if (!empty($params['sort_field'])) {
            if ($params['sort_field'] === 'start_date') {
                $orderBy = ($shouldGroup ? $startExprJoin : $startExprPlain) . " " . ($params['sort_order'] ?? 'ASC');
            } else if ($params['sort_field'] === 'km') {
                $orderBy = $kmExpr . " " . ($params['sort_order'] ?? 'ASC');
            } else {
                $orderBy = $params['sort_field'] . " " . ($params['sort_order'] ?? 'ASC');
            }
            $data = $query->group("classes_id")
            ->orderRaw($orderBy)
            ->page($params['page'], $params['limit'])
            ->select();
        } else if (!empty($params['order'])) {
            // 若传了完整 order 字符串，可按需保留或覆盖；为避免再引入子查询，建议忽略其中的 'start_date'/'km' 别名
            // $orderBy = $params['order']; // 如需保留，请确保不含子查询
            $data = $query->orderRaw($orderBy)
            ->page($params['page'], $params['limit'])
            ->select();
        }else{
            $data = $query->orderRaw($orderBy)
                ->page($params['page'], $params['limit'])
                ->select();
        }



        file_put_contents($_SERVER["DOCUMENT_ROOT"]."/../sql_debug.log", Db::getLastSql().PHP_EOL, FILE_APPEND);
        //echo db()->getLastsql()

        foreach ($data as $key => $value) {
            // 检查必要字段是否存在
            if (!isset($value['date']) || !isset($value['start_time']) || !isset($value['end_time'])) {
                // 如果缺少必要字段，跳过或使用默认值
                $data[$key]['tian'] = '未知时间';
                continue;
            }
            $roomplans = db::name("fa_course_classroomeplan")->where("classes_id", $value['classes_id'])->where("status", 1)->select();
            $weektime = [];
            foreach ($roomplans as $roomplan_key => $roomplan) {
                $weektime[] = "周" . $this->weekname($roomplan['week']) . "的" . $roomplan['daytime'];
            }
            $data[$key]['weektime'] = join("\n", $weektime);


            $data[$key]['tian'] = $this->getTian($value['date'], $value['start_time'], $value['end_time']);
            if ($data[$key]['t_id'] == 23086) {
                $data[$key]['tags'][] = "通褔社区";
            }
            $data[$key]['ocation_name'] = ($data[$key]['ocation_name']) != "" ? $data[$key]['ocation_name'] : $data[$key]['ocation_name2'];
            if ($data[$key]['classes_type'] == "2") {
                $data[$key]['tags'][] = "社区班";
                $data[$key]['tags'][] = "免费";
                $data[$key]['tags'][] = "公益课";
                $data[$key]['classes_name'] = $data[$key]['subject'];
                $data[$key]['subject_name'] = $data[$key]['subject'];
                $data[$key]['course_name'] = $data[$key]['subject'];
                $data[$key]['apply_type'] = 0;
                $data[$key]['className'] = $data[$key]['ocation_name'] . "班";
            } else if ($data[$key]['classes_type'] == "1") {
                $data[$key]['tags'][] = "学校班";
                //if ($data[$key]['is_use_integral'] == 1) {
                $data[$key]['tags'][] = "积分可用";
                //}
                $data[$key]['apply_type'] = $data[$key]['apply_type'] ?? 1;
                // 防止 subject 为空导致 mb_substr 传入 null 的弃用警告
                $data[$key]['tags'][] = mb_substr((string)($value["subject"] ?? ''), 0, 2);
            } else if ($data[$key]['classes_type'] == "3") {
                $data[$key]['tags'][] = "校外";
            } else if ($data[$key]['classes_type'] == "4") {
                $data[$key]['tags'][] = "机构";
            } else if ($data[$key]['classes_type'] == "5") {
                $data[$key]['tags'][] = "自建班";
            }
            if (!preg_match("/2/", $data[$key]['address_lv_octionlevel'])) {
                //$data[$key]['address'] = "线上";
            }
            if ($data[$key]['address_lv_octionlevel'] == "1") {
                $data[$key]['address_lv_octionlevel'] = "一级教学点";
            } else if ($data[$key]['address_lv_octionlevel'] == "2") {
                $data[$key]['address_lv_octionlevel'] = "二级教学点";
            } else if ($data[$key]['address_lv_octionlevel'] == "3" || $data[$key]['address_lv_octionlevel'] == "4") {
                $data[$key]['address_lv_octionlevel'] = "二级教学点";
            } else {
                $data[$key]['address_lv_octionlevel'] = "二级教学点";
            }

            if ($data[$key]['refund_status'] == "SUCCESS") {
                if ($data[$key]['is_applyed'] == true) {
                    db("eb_apply_form_item")->where("order_id", $data[$key]['order_id'])->update(["status" => 0, "pay_status" => "4"]);
                }
                $data[$key]['is_applyed'] = false;
            }

            // 检查时间字段是否存在
            if (isset($data[$key]['start_time']) && is_string($data[$key]['start_time'])) {
                $data[$key]['start_time'] = substr($data[$key]['start_time'], 0, 5);
            }
            if (isset($data[$key]['end_time']) && is_string($data[$key]['end_time'])) {
                $data[$key]['end_time'] = substr($data[$key]['end_time'], 0, 5);
            }

            // 防止 cover 为空或非字符串导致 substr 传入 null 的弃用警告
            if (is_string($data[$key]['cover']) && strlen($data[$key]['cover']) > 0 && substr($data[$key]['cover'], 0, 1) == "/") {
                if ($data[$key]["cover"] != "" && substr($data[$key]["cover"], 0, 4) != "http" && !preg_match("/_114_114/", $data[$key]["cover"])) {
                    $data[$key]['cover'] = createImg($_SERVER["DOCUMENT_ROOT"] . "/" . $data[$key]["cover"], "114", "114");
                }
            }
            // 防止 header_image 为空或非字符串导致 substr 传入 null 的弃用警告
            if (is_string($data[$key]['header_image']) && substr($data[$key]['header_image'], 0, 1) == "/") {
                if ($data[$key]["header_image"] != "" && substr($data[$key]["header_image"], 0, 4) != "http" && !preg_match("/_750_422/", $data[$key]["header_image"])) {
                    $data[$key]['header_image'] = createImg($_SERVER["DOCUMENT_ROOT"] . "/" . $data[$key]["header_image"], "750", "422");
                }
            }
            if (is_array($data[$key]['image']) && !empty($data[$key]['image'])) {
                foreach ($data[$key]['image'] as $k => $v) {
                    // 防止 image 项为空或非字符串导致 substr 传入 null 的弃用警告
                    if (is_string($v) && substr($v, 0, 1) == "/") {
                        if ($v != "" && substr($v, 0, 4) != "http" && !preg_match("/_750_422/", $v)) {
                            $data[$key]['image'][$k]['url'] = createImg($_SERVER["DOCUMENT_ROOT"] . "/" . $v, "750", "422");
                        } else {
                            $data[$key]['image'][$k]['url'] = Env::get('img.baseurl') . $v;
                        }
                    }
                }
            }
            $data[$key]['address'] = preg_replace('/广西壮族自治区/', '', $data[$key]['address']);
            $data[$key]['is_started'] = 1;
        }

        return $data;
    }

    public function getTian($date, $start_time, $end_time)
    {
        // 检查参数是否有效
        if (empty($date) || empty($start_time) || empty($end_time)) {
            return '未知时间';
        }

        // 检查参数是否为字符串
        if (!is_string($date) || !is_string($start_time) || !is_string($end_time)) {
            return '未知时间';
        }

        $now = time();
        $start = strtotime($date . " " . $start_time);
        $end = strtotime($date . " " . $end_time);

        // 检查时间戳是否有效
        if ($start === false || $end === false) {
            return '未知时间';
        }

        $tian = $this->formatTimeRemaining(ceil($start - $now), $date, $start_time, $end_time);
        return $tian;
    }

    public function getList()
    {
        $user = $this->auth->getUser(true);
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $school_id = $this->request->get('school_id');
        $level1 = $this->request->get('level1');
        $level2 = $this->request->get('level2');
        $latitude = $this->request->get('latitude');
        $longitude = $this->request->get('longitude');
        $classes_type = $this->request->get('classes_type');
        $table_id = $this->request->get('table_id');
        if ($table_id == "undefined") {
            $row = Db::name('fa_course_table_autoplan')
                ->alias('t')
                ->whereRaw("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00')) > UNIX_TIMESTAMP(NOW())")
                ->field("MIN(CONCAT(t.date, ' ', t.start_time, ':00')) as min_start_time, t.table_id")
                ->group("t.table_id")
                ->order("min_start_time asc")
                ->limit(1)
                ->find();
            $table_id = $row ? $row['table_id'] : db::name("fa_course_table")->order("id desc")->value("id");
        }
        $publicwelfare_id = $this->request->get('publicwelfare_id');
        // 新增学科筛选参数
        $subject_name = $this->request->get('subject_name');
        $subjectlv_id = $this->request->get('subjectlv_id/d');
        $community_id = $this->request->get('community_id');
        $current_day = $this->request->get('current_day') ?? date('Y-m-d 00:00:00');
        $ocation_ids = $this->request->get('ocation_ids');
        // 新增q参数用于课程名或班级名模糊匹配
        $q = $this->request->get('q');
        // 新增sort参数用于自定义排序
        $sort = $this->request->get('sort');

        // 新增多选参数
        $school = $this->request->get('school'); // 学校ID多选，格式：1,2,3
        $locations = $this->request->get('locations'); // 教学点ID多选，格式：1,2,3
        $orientation = $this->request->get('orientation'); // 定位多选：1=免费,2=公益,3=普惠
        $description = $this->request->get('description'); // 描述多选：1=名额有限,2=学分兑换
        $feature = $this->request->get('feature'); // 功能多选：1=预约,2=报名,3=收藏

        $subjectLv = $this->request->get('subjectLv');
        $classesType = $this->request->get('classesType');
        $firstLevelManagements = $this->request->get('firstLevelManagements');
        $secondLevelManagements = $this->request->get('secondLevelManagements');


        if ($latitude == "") {
            $latitude = 22.81000000000000;
        }
        if ($longitude == "") {
            $longitude = 108.35528564453125;
        }
        $keyword = $this->request->get('keyword');
        $order = $this->request->get('order', null);

        // 处理sort参数
        $sortField = null;
        $sortOrder = 'asc';
        if ($sort) {
            $lastUnderscorePos = strrpos($sort, '_');
            if ($lastUnderscorePos !== false) {
                $field = substr($sort, 0, $lastUnderscorePos);
                $order = substr($sort, $lastUnderscorePos + 1);

                // 字段映射转换
                $fieldMap = [
                    'distance' => 'km',
                    'time' => 'date',
                    'price' => 'price'
                ];

                $sortField = isset($fieldMap[$field]) ? $fieldMap[$field] : $field;
                $sortOrder = in_array(strtolower($order), ['desc', 'asc']) ? strtolower($order) : 'asc';
            }
        }

        $params = [
            'page' => $page,
            'limit' => $limit,
            'latitude' => $latitude,
            'longitude' => $longitude,
            'school_id' => $school_id,
            'level1' => $level1,
            'level2' => $level2,
            'keyword' => $keyword,
            'subject_name' => $subject_name,
            'subjectlv_id' => $subjectlv_id,
            'order' => $order,
            'community_id' => $community_id,
            'classes_type' => $classes_type,
            'current_day' => $current_day,
            'table_id' => $table_id,
            'publicwelfare_id' => $publicwelfare_id,
            'ocation_ids' => $ocation_ids,
            'q' => $q,
            'sort_field' => $sortField,
            'sort_order' => $sortOrder,
            // 新增多选参数
            'school' => $school,
            'locations' => $locations,
            'orientation' => $orientation,
            'description' => $description,
            'feature' => $feature,
            'subjectLv' => $subjectLv,
            'classesType' => $classesType,
            'firstLevelManagements' => $firstLevelManagements,
            'secondLevelManagements' => $secondLevelManagements,
        ];

        $list = $this->baseCourseQuery($params);

        foreach ($list as $key => $value) {
            $tags = array();

            //$list[$key]['cover'] = preg_replace('/^https?\:\/\/.*\.myqcloud\.com\//', 'https://tcimg.gxyushengwenhua.com/', $value['cover']);
            if ($value['start_date'] != null) {
                $list[$key]['start_date'] = date('Y年m月d日', strtotime($value['start_date']));
            }

            if ($list[$key]['course_name'] == "" && $list[$key]['subject'] != "") {
                $list[$key]['course_name'] = $list[$key]['subject'];
            }
            if (!empty($value['tags'])) $tags = $value['tags'];
            $list[$key]['tags'] = array_unique($tags);
            $list[$key]['description'] = preg_replace('/<title>.*<\/title>|<meta[^>]+>/Uisx', '', $list[$key]['description']);
            //$list[$key]['description'] = preg_replace('/<h2[^>]*>.*$/Uisx','', $list[$key]['description'] );
            $list[$key]['description'] = preg_replace('/<h[1-6]>.*<\/h[1-6]>|<meta[^>]+>/Uisx', '', $list[$key]['description']);
            $list[$key]['description'] = preg_replace('/<p>[^>]+>/Uisx', "<p>", $list[$key]['description']);
            $list[$key]['description'] = preg_replace('/\s+/isx', "", $list[$key]['description']);
            $list[$key]['description'] = strip_tags($list[$key]['description'], "<p><br>");
            preg_match('/^(.*?<\/p>)\s*<p/s', $list[$key]['description'], $matches);
            if (isset($matches[1])) {
                $list[$key]['description'] = $matches[1];
            }
            // 获取报名表配置信息
            $apply_form_config = $this->getApplyFormConfig($value['table_id']);
            if ($apply_form_config) {
                // 报名条件开关和内容
                $list[$key]['enable_registration_conditions'] = $apply_form_config['enable_registration_conditions'];
                $list[$key]['male_age_min'] = $apply_form_config['male_age_min'];
                $list[$key]['male_age_max'] = $apply_form_config['male_age_max'];
                $list[$key]['female_age_min'] = $apply_form_config['female_age_min'];
                $list[$key]['female_age_max'] = $apply_form_config['female_age_max'];
                $list[$key]['other_conditions'] = $apply_form_config['other_conditions'];

                // 报名须知开关和内容
                $list[$key]['enable_terms_agreement'] = $apply_form_config['enable_terms_agreement'];
                $list[$key]['terms_title'] = $apply_form_config['terms_title'];
                $list[$key]['terms_content'] = $this->format_content($apply_form_config['terms_content']);

                // 分阶段报名开关和内容
                $list[$key]['is_staged'] = $apply_form_config['is_staged'];
                $list[$key]['stage1_start_time'] = $apply_form_config['stage1_start_time'];
                $list[$key]['stage1_end_time'] = $apply_form_config['stage1_end_time'];
                $list[$key]['stage1_target'] = $apply_form_config['stage1_target'];
                $list[$key]['stage2_start_time'] = $apply_form_config['stage2_start_time'];
                $list[$key]['stage2_end_time'] = $apply_form_config['stage2_end_time'];
                $list[$key]['stage2_target'] = $apply_form_config['stage2_target'];

                // 报名数量限制开关和内容
                $list[$key]['enable_quantity_limit'] = $apply_form_config['enable_quantity_limit'];
                $list[$key]['max_courses_per_person'] = $apply_form_config['max_courses_per_person'];

                // 报名表开启开关和内容
                $list[$key]['enable_registration_form'] = $apply_form_config['enable_registration_form'];
                $list[$key]['form_title'] = $apply_form_config['form_title'];
                $list[$key]['form_description'] = $apply_form_config['form_description'];
                $list[$key]['required_fields'] = $apply_form_config['required_fields'];

                // 手签板开关和内容
                $list[$key]['enable_signature_pad'] = $apply_form_config['enable_signature_pad'];
                $list[$key]['signature_title'] = $apply_form_config['signature_title'];
                $list[$key]['signature_content'] = $apply_form_config['signature_content'];
                $list[$key]['signature_footer'] = $apply_form_config['signature_footer'];

                // 线下报名开关和内容
                $list[$key]['enable_offline_registration'] = $apply_form_config['enable_offline_registration'];
                $list[$key]['offline_quota'] = $apply_form_config['offline_quota'];
                $list[$key]['offline_payment_time_limit'] = $apply_form_config['offline_payment_time_limit'];
            } else {
                // 默认值设置
                $list[$key]['enable_registration_conditions'] = 0;
                $list[$key]['male_age_min'] = null;
                $list[$key]['male_age_max'] = null;
                $list[$key]['female_age_min'] = null;
                $list[$key]['female_age_max'] = null;
                $list[$key]['other_conditions'] = null;

                $list[$key]['enable_terms_agreement'] = 0;
                $list[$key]['terms_title'] = null;
                $list[$key]['terms_content'] = null;

                $list[$key]['is_staged'] = 0;
                $list[$key]['stage1_start_time'] = null;
                $list[$key]['stage1_end_time'] = null;
                $list[$key]['stage1_target'] = null;
                $list[$key]['stage2_start_time'] = null;
                $list[$key]['stage2_end_time'] = null;
                $list[$key]['stage2_target'] = null;

                $list[$key]['enable_quantity_limit'] = 0;
                $list[$key]['max_courses_per_person'] = null;

                $list[$key]['enable_registration_form'] = 0;
                $list[$key]['form_title'] = null;
                $list[$key]['form_description'] = null;
                $list[$key]['required_fields'] = null;

                $list[$key]['enable_signature_pad'] = 0;
                $list[$key]['signature_title'] = null;
                $list[$key]['signature_content'] = null;
                $list[$key]['signature_footer'] = null;

                $list[$key]['enable_offline_registration'] = 0;
                $list[$key]['offline_quota'] = 0;
                $list[$key]['offline_payment_time_limit'] = 24;
            }
        }


        $total = Db::name('course_table_autoplan')
            ->alias('e')
            ->find();

        if (!$list) {
            $this->error('数据不存在');
        }
        //$this->success('获取成功', $list);
        echo json_encode(array("code" => 200, "msg" => "获取成功", "data" => $list, "total" => $total));
    }


    /**
     * 获取报名表配置信息
     * @param int $table_id 课程表ID
     * @return array|null
     */
    private function getApplyFormConfig($table_id)
    {
        if (!$table_id) {
            return null;
        }

        $apply_form = Db::name('eb_apply_form')
            ->where('table_id', $table_id)
            ->where('status', 1)
            ->field('
                enable_registration_conditions, male_age_min, male_age_max, 
                female_age_min, female_age_max, other_conditions,
                enable_terms_agreement, terms_title, terms_content,
                is_staged, stage1_start_time, stage1_end_time, stage1_target,
                stage2_start_time, stage2_end_time, stage2_target,
                enable_quantity_limit, max_courses_per_person,
                enable_registration_form, form_title, form_description, required_fields,
                enable_signature_pad, signature_title, signature_content, signature_footer,
                enable_offline_registration, offline_quota, offline_payment_time_limit
            ')
            ->find();

        return $apply_form;
    }

    /**
     * 获取活动详情
     */
    public function getInfo()
    {
        $id = $this->request->get('id');
        if (!$id) {
            $this->error('参数错误');
        }

        $info = Db::name('course_table_autoplan')
            ->alias('e')
            ->join('eb_classes c', 'e.classes_id = c.id', 'LEFT')
            ->join('eb_school s', 'c.school_id = s.id', 'LEFT')
            ->join('eb_course course', 'e.table_id = course.id', 'LEFT')
            ->join('eb_class_teacher cst', 'cst.classes_id = c.id', 'LEFT')
            ->join('subject_lv sbj', 'sbj.id = c.subject_lv', 'LEFT')
            ->field('e.*, c.name as class_name, cst.teacher_id as teacher_name, 
                    s.name, course.title as course_name, c.price, 
                    sbj.name as level1, sbj.name as level2, c.labels as tags, 
                    c.intro content, c.num max_students, c.num current_students,
                    course.start_date start_time, c.address')
            ->where('e.id', $id)
            ->find();

        if (!$info) {
            $this->error('数据不存在');
        }

        $this->success('获取成功', $info);
    }

    /**
     * 获取学校班级列表（按状态分类）
     * @return \think\response\Json
     */
    public function getSchoolClasses()
    {
        $status = $this->request->get('status', 'ongoing'); // ongoing: 进行中, finished: 已结束
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $user = $this->auth->getUser(true);
        $uid = $user['uid'] ?? 0;

        $query = Db::name('course_table_autoplan')
            ->alias('t')
            ->join('fa_course_table tb', 'tb.id=t.table_id', 'INNER')
            ->join('eb_school sch', 'sch.id=t.school_id', 'LEFT')
            ->join('eb_classes c1', 'c1.id=t.classes_id', 'LEFT')
            ->join('fa_ocation o', 'o.id=t.ocation_id', 'INNER')
            ->join('fa_ocation o2', 'o.pid=o2.id', 'INNER')
            ->join('fa_subject_lv sb', 'sb.id=c1.subject_lv', 'LEFT')
            ->join('eb_apply_form_item a', "a.classes_id=c1.id AND a.user_id='{$uid}'", 'LEFT')
            ->field("
                t.id as t_id,
                t.school_id,
                sch.name as schoolName,
                t.classes_id,
                c1.name as className,
                c1.intro as description,
                c1.cover,
                c1.price,
                tb.name as course_name,
                o2.name as location_name,
                o.address,
                o.longitude,
                o.latitude,
                sb.name as subject_name,
                sb.id as subjectlv_id,
                max(CONCAT(t.date, ' ', t.start_time, ':00')) as start_time,
                (c1.num - COALESCE(c1.apply_num, 0)) as remaining_slots,
                a.id as apply_id,
                'school' as class_type
            ")
            ->where('t.table_type', 1) // 学校班级
            ->where('t.status', 1);

        // 根据状态筛选
        if ($status === 'ongoing') {
            $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '>=', time());
        } else {
            $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '<', time());
        }

        $total = $query->group("t.ocation_id,t.classes_id")->count();
        $classes = $query
            ->group("t.ocation_id,t.classes_id")
            ->order('t.date', 'desc')
            ->page($page, $limit)
            ->select();

        // 处理封面图片
        foreach ($classes as $key => $value) {
            $classes[$key]['cover'] = preg_replace('/^https?\:\/\/.*\.myqcloud\.com\//', 'https://tcimg.gxyushengwenhua.com/', $value['cover']);
        }

        // 为了兼容bootstrap-table，返回标准格式
        $result = [
            'total' => $total,
            'rows' => $classes
        ];
        return json($result);
    }

    /**
     * 获取社区班级列表（按状态分类）
     * @return \think\response\Json
     */
    public function getCommunityClasses()
    {
        $status = $this->request->get('status', 'ongoing'); // ongoing: 进行中, finished: 已结束
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $user = $this->auth->getUser(true);
        $uid = $user['uid'] ?? 0;

        $query = Db::name('course_table_autoplan_temp')
            ->alias('t')
            ->join('fa_community_publicwelfare tb2', 'tb2.id=t.publicwelfare_id', 'INNER')
            ->join('fa_community_code_config c2', 'c2.id=t.classes_id', 'LEFT')
            ->join('fa_community_course_config course2', 'course2.id=t.subject_lv', 'LEFT')
            ->join('fa_ocation o', 'o.id=t.ocation_id', 'INNER')
            ->join('fa_ocation o2', 'o.pid=o2.id', 'INNER')
            ->join('eb_apply_form_item a', "a.classes_id=c2.id AND a.user_id='{$uid}'", 'LEFT')
            ->field("
                t.id as t_id,
                t.publicwelfare_id,
                tb2.title as course_name,
                t.classes_id,
                c2.name as className,
                c2.intro as description,
                c2.cover,
                c2.price,
                o2.name as location_name,
                o.address,
                o.longitude,
                o.latitude,
                course2.name as subject_name,
                course2.id as subjectlv_id,
                max(CONCAT(t.date, ' ', t.start_time, ':00')) as start_time,
                (c2.num - COALESCE(c2.apply_num, 0)) as remaining_slots,
                a.id as apply_id,
                'community' as class_type
            ")
            ->where('t.table_type', 2) // 社区班级
            ->where('t.status', 1);

        // 根据状态筛选
        if ($status === 'ongoing') {
            $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '>=', time());
        } else {
            $query->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '<', time());
        }

        $total = $query->group("t.ocation_id,t.classes_id")->count();
        $classes = $query
            ->group("t.ocation_id,t.classes_id")
            ->order('t.date', 'desc')
            ->page($page, $limit)
            ->select();

        // 处理封面图片
        foreach ($classes as $key => $value) {
            $classes[$key]['cover'] = preg_replace('/^https?\:\/\/.*\.myqcloud\.com\//', 'https://tcimg.gxyushengwenhua.com/', $value['cover']);
        }

        // 为了兼容bootstrap-table，返回标准格式
        $result = [
            'total' => $total,
            'rows' => $classes
        ];
        return json($result);
    }

    /**
     * 获取班级统计信息
     * @return \think\response\Json
     */
    public function getClassesStats()
    {
        $user = $this->auth->getUser(true);
        $uid = $user['uid'] ?? 0;

        // 学校班级统计
        $schoolOngoing = Db::name('course_table_autoplan_temp')
            ->alias('t')
            ->where('t.table_type', 1)
            ->where('t.status', 1)
            ->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '>=', time())
            ->group("t.ocation_id,t.classes_id")
            ->count();

        $schoolFinished = Db::name('course_table_autoplan_temp')
            ->alias('t')
            ->where('t.table_type', 1)
            ->where('t.status', 1)
            ->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '<', time())
            ->group("t.ocation_id,t.classes_id")
            ->count();

        // 社区班级统计
        $communityOngoing = Db::name('course_table_autoplan_temp')
            ->alias('t')
            ->where('t.table_type', 2)
            ->where('t.status', 1)
            ->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '>=', time())
            ->group("t.ocation_id,t.classes_id")
            ->count();

        $communityFinished = Db::name('course_table_autoplan_temp')
            ->alias('t')
            ->where('t.table_type', 2)
            ->where('t.status', 1)
            ->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00'))", '<', time())
            ->group("t.ocation_id,t.classes_id")
            ->count();

        return $this->success('获取成功', [
            'school' => [
                'ongoing' => $schoolOngoing,
                'finished' => $schoolFinished,
                'total' => $schoolOngoing + $schoolFinished
            ],
            'community' => [
                'ongoing' => $communityOngoing,
                'finished' => $communityFinished,
                'total' => $communityOngoing + $communityFinished
            ]
        ]);
    }

    /**
     * 获取教学点列表
     * @return \think\response\Json
     */
    public function ocationlist()
    {
        // 强制记录日志，确保方法被调用
        $logDir = $_SERVER["DOCUMENT_ROOT"] . "/../runtime/log/";
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
        file_put_contents($logDir . "ocationlist_debug.log",
            "[" . date('Y-m-d H:i:s') . "] ocationlist方法开始执行\n", FILE_APPEND);

        // 添加调试信息
        if (isset($_GET['XDEBUG_SESSION_START']) || config('app_debug')) {
            error_log("ocationlist方法开始执行 - " . date('Y-m-d H:i:s'));
            error_log("Authorization头: " . ($_SERVER['HTTP_AUTHORIZATION'] ?? 'null'));
        }

        try {
            $user = $this->auth->getUser(true);
            $uid = $user['uid'] ?? 0;

            if (isset($_GET['XDEBUG_SESSION_START']) || config('app_debug')) {
                error_log("用户认证成功，UID: " . $uid);
            }
        } catch (\Exception $e) {
            if (isset($_GET['XDEBUG_SESSION_START']) || config('app_debug')) {
                error_log("用户认证失败: " . $e->getMessage());
            }
            // 如果认证失败，设置默认值继续执行
            $user = [];
            $uid = 0;
        }
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $keyword = $this->request->get('keyword', '');
        $level = $this->request->get('level', ''); // 教学点级别：1-一级，2-二级，3-三级，默认只显示一级
        $rel_type = $this->request->get('rel_type', ''); // 关联类型：1-学校，2-社区
        $community_id = $this->request->get('community_id', ''); // 社区ID
        $ocation_id = $this->request->get('ocation_id', ''); // 指定教学点ID
        // 获取当前位置的经纬度，可选参数
        $latitude = $this->request->get('latitude', '');
        $longitude = $this->request->get('longitude', '');

        // 检查是否提供了经纬度
        $hasLocation = !empty($latitude) && !empty($longitude);

        // 如果提供了经纬度，验证其有效性
        if ($hasLocation) {
            if (!is_numeric($latitude) || !is_numeric($longitude)) {
                return $this->error('经纬度参数格式错误');
            }

            // 经纬度范围验证
            if ($latitude < -90 || $latitude > 90 || $longitude < -180 || $longitude > 180) {
                return $this->error('经纬度参数超出有效范围');
            }
        } else {
            // 如果没有提供经纬度，使用默认值（南宁市中心）用于距离计算
            $latitude = 22.81000000000000;
            $longitude = 108.35528564453125;
        }
        $order = $this->request->get('order', 'distance'); // 排序方式：distance-距离，name-名称，level-级别

        try {
            // 构建查询
            $query = Db::name('ocation')
                ->alias('o')
                ->join('ocation o2', 'o.pid = o2.id', 'LEFT')
                ->field("
                    o.id,
                    o.id as ocation_id, 
                    o.name,
                    o.address,
                    o.longitude,
                    o.latitude,
                    o.intro,
                    o.cover,
                    o.image,
                    o.address_lv_octionlevel as level,
                    o.rel_type,
                    o.rel_id,
                    o.pid as parent_id,
                    o2.name as parent_name,
                    CONCAT(COALESCE(o2.name, ''), o.name) as full_name,
                    o.status,
                    CASE
                        WHEN o.address_lv_octionlevel = 1 THEN '一级教学点'
                        WHEN o.address_lv_octionlevel = 2 THEN '二级教学点'
                        WHEN o.address_lv_octionlevel = 3 THEN '三级教学点'
                        ELSE '未知级别'
                    END as level_name,
                    CASE
                        WHEN o.rel_type = 1 THEN '学校'
                        WHEN o.rel_type = 2 THEN '社区'
                        ELSE '其他'
                    END as type_name,
                    (6371 * ACOS(
                        COS(RADIANS({$latitude})) *
                        COS(RADIANS(COALESCE(o.latitude, 0))) *
                        COS(RADIANS(COALESCE(o.longitude, 0)) - RADIANS({$longitude})) +
                        SIN(RADIANS({$latitude})) *
                        SIN(RADIANS(COALESCE(o.latitude, 0)))
                    )) AS distance
                ")
                ->where('o.status', 1); // 只查询启用的教学点

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->where('o.name', 'like', "%{$keyword}%")
                        ->whereOr('o.address', 'like', "%{$keyword}%")
                        ->whereOr('o2.name', 'like', "%{$keyword}%");
                });
            }

            // 教学点级别筛选（默认只显示一级教学点）
            if (!empty($level) && $level !== 'all') {
                $query->where('o.address_lv_octionlevel', $level);
            }

            // 关联类型筛选
            if (!empty($rel_type)) {
                $query->where('o.rel_type', $rel_type);
            }

            // 社区ID筛选
            if (!empty($community_id)) {
                // 在添加筛选条件前，先更新fa_ocation表中community_id为空或为0的记录
                $this->updateOcationCommunityIds();

                // 直接在fa_ocation表上添加community_id条件
                $query->where('o.community_id', $community_id);
            }

            // 指定教学点ID筛选
            if (!empty($ocation_id)) {
                $query->where('o.id', $ocation_id);
            }

            // 排序逻辑
            if (!$hasLocation && $order === 'distance') {
                // 如果没有提供经纬度但要求按距离排序，改为按课程时间排序
                $order = 'course_time';
            }

            // 先按简单字段排序，距离排序在应用层处理
            switch ($order) {
                case 'distance':
                    // 距离排序将在应用层处理，这里先按ID排序
                    $query->order('o.id', 'asc');
                    break;
                case 'name':
                    $query->order('o.name', 'asc');
                    break;
                case 'level':
                    $query->order('o.address_lv_octionlevel', 'asc');
                    break;
                case 'course_time':
                    // 按最近课程时间排序
                    $query->order('o.id', 'desc'); // 先按ID排序，后面会重新排序
                    break;
                default:
                    if ($hasLocation && $order === 'distance') {
                        // 距离排序将在应用层处理
                        $query->order('o.id', 'asc');
                    } else {
                        // 没有经纬度时默认按课程时间排序
                        $query->order('o.id', 'desc'); // 先按ID排序，后面会重新排序
                    }
            }

            // 获取总数（克隆查询避免影响后续查询）
            $countQuery = clone $query;
            $total = $countQuery->count();

            // 分页查询 - 使用普通分页写法
            $startTime = microtime(true);
            $sqlLog = [];

            // 计算分页偏移量
            $offset = ($page - 1) * $limit;

            // 在调试模式下收集SQL信息
            if (isset($_GET['XDEBUG_SESSION_START']) || isset($_GET['show_sql']) || config('app_debug')) {
                // 获取查询构建器的SQL语句（不执行）
                try {
                    $buildQuery = clone $query;
                    $sqlInfo = $buildQuery->limit($offset, $limit)->fetchSql(true)->select();
                    $sqlLog['build_sql'] = $sqlInfo;
                } catch (\Exception $e) {
                    $sqlLog['build_sql_error'] = $e->getMessage();
                }
            }

            // 执行实际查询 - 使用 limit 和 offset
            $list = $query->limit($offset, $limit)->select();

            // 在调试模式下收集执行信息
            if (isset($_GET['XDEBUG_SESSION_START']) || isset($_GET['show_sql']) || config('app_debug')) {
                $endTime = microtime(true);

                // 获取最后执行的SQL语句
                $lastSql = \think\Db::getLastSql();
                $sqlLog['executed_sql'] = $lastSql;

                $sqlLog['query_info'] = [
                    'page' => $page,
                    'limit' => $limit,
                    'total_records' => $total,
                    'execution_time' => round(($endTime - $startTime) * 1000, 2) . 'ms',
                    'memory_usage' => round(memory_get_usage() / 1024 / 1024, 2) . 'MB',
                    'filters_applied' => [
                        'keyword' => !empty($keyword),
                        'level' => !empty($level),
                        'rel_type' => !empty($rel_type),
                        'community_id' => !empty($community_id),
                        'ocation_id' => !empty($ocation_id),
                        'has_location' => $hasLocation
                    ]
                ];

                // 记录到日志文件
                \think\Log::record('教学点列表SQL执行: ' . json_encode($sqlLog, JSON_UNESCAPED_UNICODE), 'info');

                // 存储调试信息
                $this->sqlDebugInfo = $sqlLog;
            }


            // 处理数据
            foreach ($list as $key => $item) {
                // 格式化距离
                if ($hasLocation && isset($item['distance'])) {
                    $list[$key]['distance'] = round($item['distance'], 2);
                    $list[$key]['distance_text'] = $item['distance'] < 1
                        ? round($item['distance'] * 1000) . 'm'
                        : round($item['distance'], 1) . 'km';
                } else {
                    $list[$key]['distance'] = 999999; // 设置一个很大的值，表示距离未知
                    $list[$key]['distance_text'] = '位置未知';
                }


                // 处理图片URL
                $list[$key]['cover_url'] = $item['cover'] ? $this->getFullImageUrl($item['cover']) : '';
                $list[$key]['image_url'] = $item['image'] ? $this->getFullImageUrl($item['image']) : '';

                // 确保经纬度为数值类型
                $list[$key]['longitude'] = $item['longitude'] ? (float)$item['longitude'] : 0.0;
                $list[$key]['latitude'] = $item['latitude'] ? (float)$item['latitude'] : 0.0;

                // 获取关联信息
                if ($item['rel_type'] == 1 && $item['rel_id']) {
                    // 学校信息
                    $school = Db::name('eb_school')
                        ->where('id', $item['rel_id'])
                        ->field('id, name, address')
                        ->find();
                    $list[$key]['related_info'] = $school;
                } elseif ($item['rel_type'] == 2 && $item['rel_id']) {
                    // 社区信息
                    $community = Db::name('fa_community')
                        ->where('id', $item['rel_id'])
                        ->field('id, name, address')
                        ->find();
                    $list[$key]['related_info'] = $community;
                } else {
                    $list[$key]['related_info'] = null;
                }

                // 获取该教学点的课程统计
                $courseStats = $this->getOcationCourseStats($item['id']);
                $list[$key]['course_stats'] = $courseStats;

                // 获取该教学点的近期课程（默认第1页，5条记录）
                $recentClasses = $this->getOcationRecentClasses($item['id'], 10, $page);
                $list[$key]['classes'] = $recentClasses;

                // 获取最近课程时间用于排序
                $list[$key]['next_course_time'] = $this->getNextCourseTime($item['id']);

                $list[$key]['tags'] = ["社区课堂"];
                $list[$key]['tags'] = ["公益课"];
            }

            // 应用层排序处理
            if ($order === 'distance' && $hasLocation) {
                // 按距离排序
                usort($list, function ($a, $b) {
                    $distanceA = isset($a['distance']) ? $a['distance'] : 999999;
                    $distanceB = isset($b['distance']) ? $b['distance'] : 999999;
                    return $distanceA <=> $distanceB;
                });
            } elseif (!$hasLocation && ($order === 'course_time' || $order === 'distance')) {
                // 按最近课程时间排序
                usort($list, function ($a, $b) {
                    // 按最近课程时间排序，没有课程的排在后面
                    if ($a['next_course_time'] === null && $b['next_course_time'] === null) {
                        return 0;
                    }
                    if ($a['next_course_time'] === null) {
                        return 1;
                    }
                    if ($b['next_course_time'] === null) {
                        return -1;
                    }
                    return $a['next_course_time'] <=> $b['next_course_time'];
                });
            }

            $responseData = [
                'list' => $list,
                'total' => $total,
                'page' => $page,
                'limit' => $limit,
                'has_more' => ($page * $limit) < $total,
                'filters' => [
                    'keyword' => $keyword,
                    'level' => $level,
                    'rel_type' => $rel_type,
                    'community_id' => $community_id,
                    'ocation_id' => $ocation_id,
                    'order' => $order,
                    'has_location' => $hasLocation
                ]
            ];

            // 在调试模式下添加SQL信息
            if (isset($this->sqlDebugInfo) && (isset($_GET['show_sql']) || isset($_GET['XDEBUG_SESSION_START']))) {
                $responseData['debug_sql'] = $this->sqlDebugInfo;
            }

            return $this->success('获取成功', $responseData);

        } catch (\Exception $e) {
            return $this->error('获取教学点列表失败：' . $e->getMessage());
        }
    }

    /**
     * 获取教学点详情
     * @return \think\response\Json
     */
    public function ocationDetail()
    {
        $id = $this->request->get('id', 0);
        $latitude = $this->request->get('latitude', '');
        $longitude = $this->request->get('longitude', '');
        $community_id = $this->request->get('community_id');
        // 验证教学点ID
        if (empty($id)) {
            return $this->error('教学点不能为空');
        }

        // 检查是否提供了经纬度
        $hasLocation = !empty($latitude) && !empty($longitude);

        // 如果提供了经纬度，验证其有效性
        if ($hasLocation) {
            if (!is_numeric($latitude) || !is_numeric($longitude)) {
                return $this->error('经纬度参数格式错误');
            }

            // 经纬度范围验证
            if ($latitude < -90 || $latitude > 90 || $longitude < -180 || $longitude > 180) {
                return $this->error('经纬度参数超出有效范围');
            }
        } else {
            // 如果没有提供经纬度，使用默认值（南宁市中心）用于距离计算
            $latitude = 22.81000000000000;
            $longitude = 108.35528564453125;
        }

        try {
            // 构建查询
            $query = Db::name('ocation')
                ->alias('o')
                ->join('ocation o2', 'o.pid = o2.id', 'LEFT')
                ->join('eb_school s', 'o.rel_type=1 and o.rel_id = s.id', 'LEFT')
                ->join('community c', 'o.rel_type=2 and o.rel_id = c.id', 'LEFT')
                ->field("
                    o.id,
                    o.id as ocation_id,
                    o.name,
                    o.address,
                    o.longitude,
                    o.latitude,
                    o.intro,
                    o.image,
                    s.name as school_name,
                    c.name as community_name,
                    o.address_lv_octionlevel as level,
                    o.image,o.header_image,o.cover,
                    o.rel_type,
                    o.rel_id,
                    o.pid as parent_id,o2.cover as cover_parent, o2.header_image as header_image_parent,
                    o2.name as parent_name,o2.cover as parent_cover, o2.header_image as parent_header_image,
                    CONCAT(COALESCE(o2.name, ''), o.name) as full_name,
                    o.status,
                    CASE
                        WHEN o.address_lv_octionlevel = 1 THEN '一级教学点'
                        WHEN o.address_lv_octionlevel = 2 THEN '二级教学点'
                        WHEN o.address_lv_octionlevel = 3 THEN '三级教学点'
                        ELSE '未知级别'
                    END as level_name,
                    CASE
                        WHEN o.rel_type = 1 THEN '学校'
                        WHEN o.rel_type = 2 THEN '社区'
                        ELSE '其他'
                    END as type_name,
                    (6371 * ACOS(
                        COS(RADIANS({$latitude})) *
                        COS(RADIANS(COALESCE(o.latitude, 0))) *
                        COS(RADIANS(COALESCE(o.longitude, 0)) - RADIANS({$longitude})) +
                        SIN(RADIANS({$latitude})) *
                        SIN(RADIANS(COALESCE(o.latitude, 0)))
                    )) AS distance
                ")
                ->where('o.id', $id)
                ->where('o.status', 1); // 只查询启用的教学点

            // 获取教学点详情
            $ocation = $query->find();
//$query->getLastSql()
            if (!$ocation) {
                return $this->error('教学点不存在或已被删除');
            }

            // 格式化距离
            if ($hasLocation && isset($ocation['distance'])) {
                $ocation['distance'] = round($ocation['distance'], 2);
                $ocation['distance_text'] = $ocation['distance'] < 1
                    ? round($ocation['distance'] * 1000) . 'm'
                    : round($ocation['distance'], 1) . 'km';
            } else {
                $ocation['distance'] = 999999;
                $ocation['distance_text'] = '位置未知';
            }
            if (!isset($ocation['iscollected'])) {
                $ocation['iscollected'] = $this->isCollected($id, 1);
            }
            // 处理图片URL
            $ocation['cover'] = $ocation['cover_url'] = $ocation['cover'] ? getImg($ocation['cover'], 200, 200) : '';
            $ocation['header_image'] = $ocation['header_image_url'] = $ocation['header_image'] ? getImg($ocation['header_image'], 750, 422) : '';
            if ($ocation['header_image'] == "" && $ocation['header_image_parent'] != "") {
                $ocation['header_image'] = $ocation['header_image_parent'];
            } elseif ($ocation['header_image'] == "" && is_array($ocation['image']) && !empty($ocation['image']) && isset($ocation['image'][0]['url'])) {
                $ocation['header_image'] = $ocation['image_url'] = getImg($ocation['image'][0]['url'], 750, 422);
            } else {
                // 如果header_image为空且没有其他可用的图片，使用默认图片
                if ($ocation['header_image'] == "") {
                    $ocation['header_image'] = "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a_750_422.png";
                }
            }

            if (is_string($ocation['image'])) {
                $ocation['image'] = json_decode($ocation['image'], 1);
            }

            if (is_array($ocation['image'])) {
                foreach ($ocation['image'] as $key => $item) {
                    // 检查$item是否为数组且包含url键
                    if (is_array($item) && isset($item['url'])) {
                        $ocation['image'][$key]['url'] = getImg($item['url'], 750, 422);
                        //$ocation['image'][$key]['url'] = $item['url'];
                    } else {
                        // 如果不是有效的数组或没有url键，设置为默认图片
                        $ocation['image'][$key]['url'] = "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png";
                    }
                }
            }


            if ($ocation['cover'] == "") {
                $ocation['cover'] = $ocation['cover_parent'];
            }

            // 确保经纬度为数值类型
            $ocation['longitude'] = $ocation['longitude'] ? (float)$ocation['longitude'] : 0.0;
            $ocation['latitude'] = $ocation['latitude'] ? (float)$ocation['latitude'] : 0.0;
            if ($ocation["school_name"] == "") {
                $ocation["school_name"] = $ocation["parent_name"];
            }
            // 获取关联信息
            if ($ocation['rel_type'] == 1 && $ocation['rel_id']) {
                // 学校信息
                $school = Db::name('eb_school')
                    ->where('id', $ocation['rel_id'])
                    ->field('id, name, address, phone, intro, cover, image')
                    ->find();
                if ($school) {
                    $school['cover'] = $school['cover_url'] = $school['cover'] ? getImg($school['cover'], 200, 200) : '';
                    if (empty($school['image'])) {
                        $school['image'] = [];
                    } else {
                        $school['image'] = json_decode($school['image'], true);
                        if (is_string($school['image'][0])) {
                            $school['header_image'] = json_decode($school['image'][0], true);
                        }
                        foreach ($school['image'] as $key => $item) {
                            $school['image'][$key]['url'] = getImg($school['image'][$key]['url'], 750, 422);
                        }
                    }
                }
                $ocation['related_info'] = $school;
            } elseif ($ocation['rel_type'] == 2 && $ocation['rel_id']) {
                // 社区信息
                $community = Db::name('community')
                    ->where('id', $ocation['rel_id'])
                    ->field('id, name, address, phone, intro, cover, image')
                    ->find();
                if ($community) {
                    $community['cover'] = $community['cover'] ?? "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png";
                    $community['image'] = $community['image'] ?? array(
                        array("url" => "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png", "title" => "图片1"),
                        array("url" => "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png", "title" => "图片2"),
                        array("url" => "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png", "title" => "图片3"),
                        array("url" => "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png", "title" => "图片4"),
                        array("url" => "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a.png", "title" => "图片5")
                    );
                    $community['cover_url'] = $this->getFullImageUrl($community['cover']);
                    $community['image_url'] = $this->getFullImageUrl($community['image'][0]['url']);
                }
                $ocation['related_info'] = $community;
            } else {
                $ocation['related_info'] = null;
            }

            // 设置默认图片
            $defaultImageUrl = "https://dev002.gxyushengwenhua.com/uploads/20241223/1c2e43fffe96d0dc0374cd5b9307868a_750_422.png";
            $defaultImages = array(
                array("url" => $defaultImageUrl, "title" => "图片1"),
                array("url" => $defaultImageUrl, "title" => "图片2"),
                array("url" => $defaultImageUrl, "title" => "图片3"),
                array("url" => $defaultImageUrl, "title" => "图片4"),
                array("url" => $defaultImageUrl, "title" => "图片5")
            );

            // 如果image为空，则设置默认值
            if (empty($ocation["image"]) || $ocation["image"] == "[]") {
                $ocation["image"] = $defaultImages;
            }
            // 如果cover为空，则设置默认值
            if (empty($ocation["cover"])) {
                $ocation["cover"] = $defaultImageUrl;
            }

            // 如果header_image为空，则设置默认值
            if (empty($ocation["header_image"])) {
                $ocation["header_image"] = $defaultImageUrl;
            }

            // 如果related_info的image为空，则设置默认值
            if (!empty($ocation['related_info']) && empty($ocation['related_info']['image'])) {
                $ocation['related_info']['image'] = $defaultImages;
            }

            // 如果related_info的cover为空，则设置默认值
            if (!empty($ocation['related_info']) && empty($ocation['related_info']['cover'])) {
                $ocation['related_info']['cover'] = $defaultImageUrl;
            }

            // 获取该教学点的课程统计
            $courseStats = $this->getOcationCourseStats($ocation['id']);
            $ocation['course_stats'] = $courseStats;
            $ocation['name'] = preg_replace("/教学点$/U", "", $ocation['name']) . "教学点";

            // 获取该教学点的近期课程（更多数量，支持分页）
            $classesPage = $this->request->get('page', 1); // 课程页码
            $classesLimit = $this->request->get('size', 10); // 课程每页数量
            //$recentClasses = $this->getOcationRecentClasses($ocation['id'], $classesLimit, $classesPage);
            //$ocation['recent_classes'] = $recentClasses;

            // 获取该教学点的历史课程（最近完成的课程）
            //$historyClasses = $this->getOcationHistoryClasses($ocation['id'], 5);
            //$ocation['history_classes'] = $historyClasses;

            // 获取子级教学点
            //$subOcations = $this->getSubOcations($ocation['id']);
            //$ocation['sub_ocations'] = $subOcations;

            // 获取该教学点及其子教学点的最近上课信息（支持分页和筛选）
            $page = $this->request->get('page', 1); // 最近课程页码
            $pagesize = $this->request->get('pagesize', 10); // 最近课程每页数量

            // 筛选条件
            $lessonsFilters = [
                'classes_type' => $this->request->get('classes_type'), // 课程类型：1-学校课程，2-社区课程
                'community_id' => $this->request->get('community_id'), // 社区ID筛选
                'is_free' => $this->request->get('is_free') // 是否免费：1-免费，0-收费
            ];

            // 获取该教学点及其子教学点的最近上课信息（支持分页和筛选）
            try {
                $recentLessons = $this->getRecentLessons($ocation['id'], $pagesize, $page, $lessonsFilters);

                // 检查返回结果是否有效
                if (!is_array($recentLessons)) {
                    $recentLessons = [];
                }
                $ocation['recent_lessons'] = $recentLessons;
            } catch (\Exception $e) {
                // 记录错误日志
                // Log::error("获取教学点最近课程失败: " . $e->getMessage());
                $ocation['recent_lessons'] = [];
            }
            // 获取所有相关教学点的今日课程
            //$todayClasses = $this->getTodayClasses($ocation['id']);
            //$ocation['today_classes'] = $todayClasses;

            return $this->success('获取成功', $ocation);

        } catch (\Exception $e) {
            return $this->error('获取教学点详情失败：' . $e->getMessage());
        }
    }

    /**
     * 获取教学点的课程统计信息
     * @param int $ocation_id 教学点ID
     * @return array
     */
    private function getOcationCourseStats($ocation_id)
    {
        try {
            // 检查参数是否有效
            if (!is_numeric($ocation_id) || $ocation_id <= 0) {
                return [
                    'total' => 0,
                    'ongoing' => 0,
                    'finished' => 0,
                    'school' => 0,
                    'community' => 0
                ];
            }

            // 总课程数
            $totalCourses = Db::name('course_table_autoplan_temp')
                ->where('ocation_id', $ocation_id)
                ->where('status', 1)
                ->count();

            // 进行中的课程数
            $ongoingCourses = Db::name('course_table_autoplan_temp')
                ->where('ocation_id', $ocation_id)
                ->where('status', 1)
                ->where("UNIX_TIMESTAMP(CONCAT(date, ' ', start_time, ':00'))", '>=', time())
                ->count();

            // 已结束的课程数
            $finishedCourses = Db::name('course_table_autoplan_temp')
                ->where('ocation_id', $ocation_id)
                ->where('status', 1)
                ->where("UNIX_TIMESTAMP(CONCAT(date, ' ', start_time, ':00'))", '<', time())
                ->count();

            // 学校课程数
            $schoolCourses = Db::name('course_table_autoplan_temp')
                ->where('ocation_id', $ocation_id)
                ->where('table_type', 1)
                ->where('status', 1)
                ->count();

            // 社区课程数
            $communityCourses = Db::name('course_table_autoplan_temp')
                ->where('ocation_id', $ocation_id)
                ->where('table_type', 2)
                ->where('status', 1)
                ->count();

            return [
                'total' => $totalCourses,
                'ongoing' => $ongoingCourses,
                'finished' => $finishedCourses,
                'school' => $schoolCourses,
                'community' => $communityCourses
            ];

        } catch (\Exception $e) {
            return [
                'total' => 0,
                'ongoing' => 0,
                'finished' => 0,
                'school' => 0,
                'community' => 0
            ];
        }
    }

    /**
     * 获取教学点的近期课程（直接调用baseCourseQuery，包括子教学点）
     * @param int $ocation_id 教学点ID
     * @param int $limit 限制数量
     * @param int $page 页码，默认为1
     * @return array
     */
    private function getOcationRecentClasses($ocation_id, $limit = 5, $page = 1)
    {
        try {
            // 获取该教学点及其所有子教学点的ID
            $ocationIds = $this->getAllSubOcationIds($ocation_id);

            // 直接调用baseCourseQuery方法
            $params = [
                'page' => $page,
                'limit' => $limit,
                'ocation_ids' => $ocationIds,
                'include_sub_ocations' => true,
                'order' => 'start_time asc' // 按开始时间排序
            ];

            $classes = $this->baseCourseQuery($params);

            // 处理课程数据，补充一些特定字段
            foreach ($classes as $key => $class) {
                // 检查必要字段是否存在
                if (!isset($class['date']) || !isset($class['start_time']) || !isset($class['end_time'])) {
                    // 如果缺少必要字段，跳过或使用默认值
                    $classes[$key]['date_text'] = '未知日期';
                    $classes[$key]['time_text'] = '未知时间';
                    $classes[$key]['datetime_text'] = '未知时间';
                    $classes[$key]['time_remaining'] = '未知';
                    $classes[$key]['status_text'] = '未知状态';
                    continue;
                }

                // 基础时间格式化（baseCourseQuery已有大部分字段）
                if (isset($class['date']) && is_string($class['date']) && strtotime($class['date']) !== false) {
                    $classes[$key]['date_text'] = date('Y-m-d', strtotime($class['date']));
                } else {
                    $classes[$key]['date_text'] = '未知日期';
                }

                if (isset($class['start_time']) && isset($class['end_time']) &&
                    is_string($class['start_time']) && is_string($class['end_time'])) {
                    $classes[$key]['time_text'] = $class['start_time'] . '-' . $class['end_time'];
                    $classes[$key]['datetime_text'] = $classes[$key]['date_text'] . ' ' . $classes[$key]['time_text'];

                    // 计算距离现在的时间
                    $classTime = strtotime($class['date'] . ' ' . $class['start_time']);
                    if ($classTime !== false) {
                        $timeDiff = $classTime - time();
                        $classes[$key]['time_remaining'] = $this->formatTimeRemaining($timeDiff);
                        $classes[$key]['status_text'] = $timeDiff > 0 ? '即将开始' : '进行中';
                    } else {
                        $classes[$key]['time_remaining'] = '未知';
                        $classes[$key]['status_text'] = '未知状态';
                    }
                } else {
                    $classes[$key]['time_text'] = '未知时间';
                    $classes[$key]['datetime_text'] = '未知时间';
                    $classes[$key]['time_remaining'] = '未知';
                    $classes[$key]['status_text'] = '未知状态';
                }

                // 教学点信息
                $classes[$key]['is_main_ocation'] = $class['ocation_id'] == $ocation_id;

                // 处理图片URL（如果baseCourseQuery没有处理的话）
                if (!isset($class['course_image_url']) && isset($class['course_image'])) {
                    if (method_exists($this, 'getFullImageUrl')) {
                        $classes[$key]['course_image_url'] = $class['course_image'] ? $this->getFullImageUrl($class['course_image']) : '';
                    } else {
                        $classes[$key]['course_image_url'] = $class['course_image'] ? $class['course_image'] : '';
                    }
                }
                if (!isset($class['teacher_avatar_url'])) {
                    $classes[$key]['teacher_avatar_url'] = ''; // 暂时为空，可以后续扩展
                }
            }

            return $classes;

        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * 格式化剩余时间
     * @param int $seconds 剩余秒数
     * @param string $date 日期
     * @param string $start_time 开始时间
     * @param string $end_time 结束时间
     * @return string
     */
    private function formatTimeRemaining($seconds, $date = '', $start_time = '', $end_time = '')
    {
        if ($seconds <= 0 && $seconds > -90) {
            return '正在进行';
        }
        if ($seconds < -90) {
            return '已结束';
        }

        $days = floor($seconds / 86400);
        $hours = floor(($seconds % 86400) / 3600);
        $minutes = floor(($seconds % 3600) / 60);

        // 检查日期是否有效
        if (!empty($date) && is_string($date)) {
            if ($date == date("Y-m-d")) {
                if ($hours > 0) {
                    return $hours . '小时后';
                } elseif ($minutes > 0) {
                    return $minutes . '分钟后';
                } else {
                    return '即将开始';
                }
            } elseif ($date == date("Y-m-d", strtotime("+1 day"))) {
                return '明天';
            } elseif ($date == date("Y-m-d", strtotime("+2 day"))) {
                return '后天';
            } elseif ($date > date("Y-m-d", strtotime("+2 day"))) {
                return $days . '天后';
            }
        }

        // 如果没有提供日期或日期无效，使用默认逻辑
        if ($days > 0) {
            return $days . '天后';
        } elseif ($hours > 0) {
            return $hours . '小时后';
        } elseif ($minutes > 0) {
            return $minutes . '分钟后';
        } else {
            return '即将开始';
        }
    }

    /**
     * 获取教学点的最近课程时间
     * @param int $ocation_id 教学点ID
     * @return int|null 最近课程的时间戳，没有课程返回null
     */
    private function getNextCourseTime($ocation_id)
    {
        try {
            $nextCourse = Db::name('course_table_autoplan_temp')
                ->where('ocation_id', $ocation_id)
                ->where('status', 1)
                ->where("UNIX_TIMESTAMP(CONCAT(date, ' ', start_time, ':00'))", '>=', time())
                ->order("UNIX_TIMESTAMP(CONCAT(date, ' ', start_time, ':00'))", 'asc')
                ->field("UNIX_TIMESTAMP(CONCAT(date, ' ', start_time, ':00')) as course_timestamp")
                ->find();

            return $nextCourse ? $nextCourse['course_timestamp'] : null;

        } catch (\Exception $e) {
            return null;
        }
    }

    /**
     * 获取完整的图片URL
     * @param string $imagePath 图片路径
     * @return string
     */
    private function getFullImageUrl($imagePath)
    {
        // 检查参数是否有效
        if (empty($imagePath) || !is_string($imagePath)) {
            return '';
        }

        // 如果已经是完整URL，直接返回
        if (strpos($imagePath, 'http') === 0) {
            return $imagePath;
        }

        // 获取域名
        try {
            $domain = $this->request->domain();
        } catch (\Exception $e) {
            // 如果获取域名失败，使用空字符串
            $domain = '';
        }

        // 确保路径以 / 开头
        if (strpos($imagePath, '/') !== 0) {
            $imagePath = '/' . $imagePath;
        }

        return $domain . $imagePath;
    }

    /**
     * 获取教学点的历史课程
     * @param int $ocation_id 教学点ID
     * @param int $limit 限制数量
     * @return array
     */
    private function getOcationHistoryClasses($ocation_id, $limit = 5)
    {
        try {
            // 构建查询，获取已结束的课程
            $query = Db::name('course_table_autoplan_temp')
                ->alias('t')
                ->join('eb_school sch', 'sch.id=t.school_id', 'LEFT')
                ->join('eb_classes c1', 't.table_type=1 AND c1.id=t.classes_id', 'LEFT')
                ->join('fa_ocation_class c3', 't.table_type=2 AND c3.id=t.classes_id', 'LEFT')
                ->join('fa_community_code_config c2', 't.table_type=2 AND c2.id=t.classes_id', 'LEFT')
                ->join('fa_community_course_config course2', 't.table_type=2 AND course2.id=t.subject_lv', 'LEFT')
                ->join('fa_course_table tb', 't.table_type=1 AND tb.id=t.table_id', 'left')
                ->join('fa_community_publicwelfare tb2', 't.table_type=2 AND tb2.id=t.publicwelfare_id', 'left')
                ->join('fa_ocation o', 'o.id=t.ocation_id', 'INNER')
                ->join('fa_subject_lv sb', 't.table_type=1 AND sb.id=c1.subject_lv', 'LEFT')
                ->field("
                    t.id,
                    t.date,
                    t.start_time,
                    t.end_time,
                    t.table_type,
                    COALESCE(c1.name, CONCAT(o.name,course2.name,'课堂')) as course_name,
                    COALESCE(sb.name, course2.name) as subject_name,
                    sch.name as school_name,
                    tb.name as course_title,
                    COALESCE(c1.cover, course2.cover) as course_image,
                    '' as teacher_name,
                    '' as teacher_avatar
                ")
                ->where('t.ocation_id', $ocation_id)
                ->where('t.status', 1)
                ->where("UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.end_time, ':00'))", '<', time())
                ->order('t.date', 'desc')
                ->order('t.start_time', 'desc')
                ->limit($limit);

            $classes = $query->select();

            // 处理课程数据
            foreach ($classes as $key => $class) {
                // 格式化时间
                if (isset($class['date']) && isset($class['start_time']) && isset($class['end_time']) && is_string($class['start_time']) && is_string($class['end_time'])) {
                    $classes[$key]['date_text'] = date('Y-m-d', strtotime($class['date']));
                    $classes[$key]['time_text'] = substr($class['start_time'], 0, 5) . '-' . substr($class['end_time'], 0, 5);
                    $classes[$key]['datetime_text'] = $classes[$key]['date_text'] . ' ' . $classes[$key]['time_text'];
                } else {
                    $classes[$key]['date_text'] = '未知日期';
                    $classes[$key]['time_text'] = '未知时间';
                    $classes[$key]['datetime_text'] = '未知时间';
                }

                // 计算距离现在的时间
                if (isset($class['date']) && isset($class['end_time']) && is_string($class['date']) && is_string($class['end_time'])) {
                    $classTime = strtotime($class['date'] . ' ' . $class['end_time']);
                    $timeDiff = time() - $classTime;
                    if (method_exists($this, 'formatTimePassed')) {
                        $classes[$key]['time_passed'] = $this->formatTimePassed($timeDiff);
                    } else {
                        $classes[$key]['time_passed'] = '已结束';
                    }
                } else {
                    $classes[$key]['time_passed'] = '未知时间';
                }

                // 处理图片URL
                if (isset($class['course_image'])) {
                    if (method_exists($this, 'getFullImageUrl')) {
                        $classes[$key]['course_image_url'] = $class['course_image'] ? $this->getFullImageUrl($class['course_image']) : '';
                    } else {
                        $classes[$key]['course_image_url'] = $class['course_image'] ? $class['course_image'] : '';
                    }
                } else {
                    $classes[$key]['course_image_url'] = '';
                }
                $classes[$key]['teacher_avatar_url'] = ''; // 暂时为空，可以后续扩展

                // 课程状态
                $classes[$key]['status_text'] = '已结束';
            }

            return $classes;

        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * 获取子级教学点
     * @param int $parent_id 父级教学点ID
     * @return array
     */
    private function getSubOcations($parent_id)
    {
        try {
            $subOcations = Db::name('ocation')
                ->where('pid', $parent_id)
                ->where('status', 1)
                ->field('id, name, address, address_lv_octionlevel as level, cover, image')
                ->order('address_lv_octionlevel', 'asc')
                ->order('name', 'asc')
                ->select();

            // 处理数据
            foreach ($subOcations as $key => $item) {
                // 检查级别字段是否存在
                if (isset($item['level'])) {
                    if (method_exists($this, 'getLevelName')) {
                        $subOcations[$key]['level_name'] = $this->getLevelName($item['level']);
                    } else {
                        $subOcations[$key]['level_name'] = '未知级别';
                    }
                } else {
                    $subOcations[$key]['level_name'] = '未知级别';
                }

                // 处理封面图片URL
                if (isset($item['cover'])) {
                    if (method_exists($this, 'getFullImageUrl')) {
                        $subOcations[$key]['cover_url'] = $item['cover'] ? $this->getFullImageUrl($item['cover']) : '';
                    } else {
                        $subOcations[$key]['cover_url'] = $item['cover'] ? $item['cover'] : '';
                    }
                } else {
                    $subOcations[$key]['cover_url'] = '';
                }

                // 处理图片URL
                if (isset($item['image'])) {
                    if (method_exists($this, 'getFullImageUrl')) {
                        $subOcations[$key]['image_url'] = $item['image'] ? $this->getFullImageUrl($item['image']) : '';
                    } else {
                        $subOcations[$key]['image_url'] = $item['image'] ? $item['image'] : '';
                    }
                } else {
                    $subOcations[$key]['image_url'] = '';
                }

                // 获取子级教学点的课程统计
                if (isset($item['id'])) {
                    $courseStats = $this->getOcationCourseStats($item['id']);
                    $subOcations[$key]['course_stats'] = $courseStats;
                } else {
                    $subOcations[$key]['course_stats'] = [
                        'total' => 0,
                        'ongoing' => 0,
                        'finished' => 0,
                        'school' => 0,
                        'community' => 0
                    ];
                }
            }

            return $subOcations;

        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * 格式化已过去的时间
     * @param int $seconds 已过去的秒数
     * @return string
     */
    private function formatTimePassed($seconds)
    {
        // 检查参数是否有效
        if (!is_numeric($seconds)) {
            return '刚刚结束';
        }

        if ($seconds <= 0) {
            return '刚刚结束';
        }

        $days = floor($seconds / 86400);
        $hours = floor(($seconds % 86400) / 3600);
        $minutes = floor(($seconds % 3600) / 60);

        if ($days > 0) {
            return $days . '天前';
        } elseif ($hours > 0) {
            return $hours . '小时前';
        } elseif ($minutes > 0) {
            return $minutes . '分钟前';
        } else {
            return '刚刚结束';
        }
    }

    /**
     * 获取级别名称
     * @param int $level 级别
     * @return string
     */
    private function getLevelName($level)
    {
        // 检查参数是否有效
        if (!is_numeric($level)) {
            return '未知级别';
        }

        switch ($level) {
            case 1:
                return '一级教学点';
            case 2:
                return '二级教学点';
            case 3:
            case 4:
            case 5:
                return '教学点教室';
            default:
                return '未知级别';
        }
    }

    /**
     * 获取教学点及其子教学点的最近上课信息（直接调用baseCourseQuery，支持分页和条件筛选）
     * @param int $ocation_id 教学点ID
     * @param int $limit 限制数量
     * @param int $page 页码，默认为1
     * @param array $filters 筛选条件
     * @return array
     */
    private function getRecentLessons($ocation_id, $limit = 10, $page = 1, $filters = [])
    {
        try {
            // 获取该教学点及其所有子教学点的ID
            $ocationIds = $this->getAllSubOcationIds($ocation_id);

            // 直接调用baseCourseQuery方法，获取最近的课程（包括正在进行和即将开始的）
            $params = [
                'page' => $page,
                'limit' => $limit,
                'ocation_ids' => $ocationIds,
                'include_sub_ocations' => true,
                'order' => 'start_time asc', // 按开始时间排序
                'time_filter' => 'recent', // 最近课程筛选
                'classes_type' => $filters['classes_type'] ?? null, // 课程类型筛选
                'community_id' => $filters['community_id'] ?? null, // 社区ID筛选
                'is_free' => $filters['is_free'] ?? null // 是否免费筛选
            ];

            $lessons = $this->baseCourseQuery($params);

            // 处理课程数据，补充一些特定字段
            foreach ($lessons as $key => $lesson) {
                // 基础时间格式化（baseCourseQuery已有大部分字段）
                //$lessons[$key]['date_text'] = date('Y-m-d', strtotime($lesson['start_date']));
                //$lessons[$key]['time_text'] = $lessons[$key]['start_date'] . '-' . $lessons[$key]['end_date'];
                //$lessons[$key]['datetime_text'] = $lessons[$key]['date_text'] . ' ' . $lessons[$key]['time_text'];
                // 计算课程状态和时间信息
                $currentTime = time();

                // 检查必要字段是否存在
                if (!isset($lesson['start_date']) || !isset($lesson['start_time']) || !isset($lesson['end_time'])) {
                    // 如果缺少必要字段，跳过或使用默认值
                    $lessons[$key]['status'] = 'unknown';
                    $lessons[$key]['status_text'] = '未知状态';
                    $lessons[$key]['time_info'] = '未知时间';
                    continue;
                }

                // 检查字段是否为空
                if (empty($lesson['start_date']) || empty($lesson['start_time']) || empty($lesson['end_time'])) {
                    // 如果字段为空，跳过或使用默认值
                    $lessons[$key]['status'] = 'unknown';
                    $lessons[$key]['status_text'] = '未知状态';
                    $lessons[$key]['time_info'] = '未知时间';
                    continue;
                }

                // 确保日期和时间是字符串类型
                $startDate = is_string($lesson['start_date']) ? $lesson['start_date'] : '';
                $startTime = is_string($lesson['start_time']) ? $lesson['start_time'] : '';
                $endTime = is_string($lesson['end_time']) ? $lesson['end_time'] : '';

                // 检查日期和时间是否有效
                if (empty($startDate) || empty($startTime) || empty($endTime)) {
                    $lessons[$key]['status'] = 'unknown';
                    $lessons[$key]['status_text'] = '未知状态';
                    $lessons[$key]['time_info'] = '未知时间';
                    continue;
                }

                $startTimestamp = strtotime($startDate . ' ' . $startTime);
                $endTimestamp = strtotime($startDate . ' ' . $endTime);

                // 检查时间戳是否有效
                if ($startTimestamp === false || $endTimestamp === false) {
                    $lessons[$key]['status'] = 'unknown';
                    $lessons[$key]['status_text'] = '未知状态';
                    $lessons[$key]['time_info'] = '未知时间';
                    continue;
                }

                if ($currentTime < $startTimestamp) {
                    $lessons[$key]['status'] = 'upcoming';
                    $lessons[$key]['status_text'] = '即将开始';
                    // 检查方法是否存在
                    if (method_exists($this, 'formatTimeRemaining')) {
                        $lessons[$key]['time_info'] = $this->formatTimeRemaining($startTimestamp - $currentTime);
                    } else {
                        $lessons[$key]['time_info'] = '即将开始';
                    }
                } elseif ($currentTime >= $startTimestamp && $currentTime <= $endTimestamp) {
                    $lessons[$key]['status'] = 'ongoing';
                    $lessons[$key]['status_text'] = '正在进行';
                    $lessons[$key]['time_info'] = '进行中';
                } else {
                    $lessons[$key]['status'] = 'finished';
                    $lessons[$key]['status_text'] = '刚结束';
                    // 检查方法是否存在
                    if (method_exists($this, 'formatTimePassed')) {
                        $lessons[$key]['time_info'] = $this->formatTimePassed($currentTime - $endTimestamp);
                    } else {
                        $lessons[$key]['time_info'] = '已结束';
                    }
                }

                // 检查start_date是否有效
                if (!empty($lesson['start_date']) && is_string($lesson['start_date']) && strtotime($lesson['start_date']) !== false) {
                    $lessons[$key]['start_date'] = date('Y年m月d日', strtotime($lesson['start_date']));
                } else {
                    $lessons[$key]['start_date'] = '未知日期';
                }

                // 检查start_time是否有效
                if (!empty($lesson['start_time']) && is_string($lesson['start_time'])) {
                    $lessons[$key]['start_time'] = substr($lesson['start_time'], 0, 5);
                } else {
                    $lessons[$key]['start_time'] = '';
                }

                // 是否为主教学点的课程 - 添加字段存在性检查
                if (isset($lesson['ocation_id']) && $lesson['ocation_id'] !== null) {
                    $lessons[$key]['is_main_ocation'] = $lesson['ocation_id'] == $ocation_id;
                } else {
                    $lessons[$key]['is_main_ocation'] = false;
                }

                // 处理图片URL（如果baseCourseQuery没有处理的话）
                if (!isset($lesson['course_image_url']) && isset($lesson['course_image'])) {
                    if (method_exists($this, 'getFullImageUrl')) {
                        $lessons[$key]['course_image_url'] = $lesson['course_image'] ? $this->getFullImageUrl($lesson['course_image']) : '';
                    } else {
                        $lessons[$key]['course_image_url'] = $lesson['course_image'] ? $lesson['course_image'] : '';
                    }
                }
                if (!isset($lesson['teacher_avatar_url'])) {
                    $lessons[$key]['teacher_avatar_url'] = ''; // 暂时为空，可以后续扩展
                }
            }

            return $lessons;

        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * 获取教学点及其子教学点的今日课程
     * @param int $ocation_id 教学点ID
     * @return array
     */
    private function getTodayClasses($ocation_id)
    {
        try {
            // 获取该教学点及其所有子教学点的ID
            $ocationIds = $this->getAllSubOcationIds($ocation_id);

            // 今日日期
            $today = date('Y-m-d');

            // 构建查询，获取今日的所有课程
            $query = Db::name('course_table_autoplan_temp')
                ->alias('t')
                ->join('eb_school sch', 'sch.id=t.school_id', 'LEFT')
                ->join('eb_classes c1', 'c1.id=t.classes_id', 'LEFT')
                ->join('fa_community_code_config c2', 't.table_type=2 AND c2.id=t.classes_id', 'LEFT')
                ->join('fa_community_course_config course2', 't.table_type=2 AND course2.id=t.subject_lv', 'LEFT')
                ->join('fa_course_table tb', 't.table_type=1 AND tb.id=t.table_id', 'left')
                ->join('fa_community_publicwelfare tb2', 't.table_type=2 AND tb2.id=t.publicwelfare_id', 'left')
                ->join('fa_ocation o', 'o.id=t.ocation_id', 'INNER')
                ->join('fa_subject_lv sb', 't.table_type=1 AND sb.id=c1.subject_lv', 'LEFT')
                ->field("
                    t.id,
                    t.date,
                    t.start_time,
                    t.end_time,
                    t.table_type,
                    t.ocation_id,
                    o.name as ocation_name,
                    o.address_lv_octionlevel as ocation_level,
                    COALESCE(c1.name, CONCAT(o.name,course2.name,'课堂')) as course_name,
                    COALESCE(sb.name, course2.name) as subject_name,
                    sch.name as school_name,
                    tb.name as course_title,
                    COALESCE(c1.cover, course2.cover) as course_image,
                    UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.start_time, ':00')) as start_timestamp,
                    UNIX_TIMESTAMP(CONCAT(t.date, ' ', t.end_time, ':00')) as end_timestamp
                ")
                ->where('t.ocation_id', 'in', $ocationIds)
                ->where('t.date', $today)
                ->where('t.status', 1)
                ->order('t.start_time', 'asc');

            $todayClasses = $query->select();

            // 处理课程数据
            foreach ($todayClasses as $key => $class) {
                // 检查必要字段是否存在
                if (!isset($class['start_time']) || !isset($class['end_time'])) {
                    // 如果缺少必要字段，跳过或使用默认值
                    $todayClasses[$key]['status'] = 'unknown';
                    $todayClasses[$key]['status_text'] = '未知状态';
                    $todayClasses[$key]['time_info'] = '未知时间';
                    $todayClasses[$key]['time_text'] = '未知时间';
                    continue;
                }

                // 格式化时间
                if (isset($class['start_time']) && isset($class['end_time']) && is_string($class['start_time']) && is_string($class['end_time'])) {
                    $todayClasses[$key]['time_text'] = substr($class['start_time'], 0, 5) . '-' . substr($class['end_time'], 0, 5);
                } else {
                    $todayClasses[$key]['time_text'] = '未知时间';
                }

                // 判断课程状态
                $currentTime = time();

                // 检查时间戳是否存在
                if (!isset($class['start_timestamp']) || !isset($class['end_timestamp'])) {
                    // 如果缺少时间戳，跳过或使用默认值
                    $todayClasses[$key]['status'] = 'unknown';
                    $todayClasses[$key]['status_text'] = '未知状态';
                    $todayClasses[$key]['time_info'] = '未知时间';
                    continue;
                }

                $startTime = $class['start_timestamp'];
                $endTime = $class['end_timestamp'];

                if ($currentTime < $startTime) {
                    $todayClasses[$key]['status'] = 'upcoming';
                    $todayClasses[$key]['status_text'] = '即将开始';
                    // 检查方法是否存在
                    if (method_exists($this, 'formatTimeRemaining')) {
                        $todayClasses[$key]['time_info'] = $this->formatTimeRemaining($startTime - $currentTime);
                    } else {
                        $todayClasses[$key]['time_info'] = '即将开始';
                    }
                } elseif ($currentTime >= $startTime && $currentTime <= $endTime) {
                    $todayClasses[$key]['status'] = 'ongoing';
                    $todayClasses[$key]['status_text'] = '正在进行';
                    $todayClasses[$key]['time_info'] = '进行中';
                } else {
                    $todayClasses[$key]['status'] = 'finished';
                    $todayClasses[$key]['status_text'] = '已结束';
                    // 检查方法是否存在
                    if (method_exists($this, 'formatTimePassed')) {
                        $todayClasses[$key]['time_info'] = $this->formatTimePassed($currentTime - $endTime);
                    } else {
                        $todayClasses[$key]['time_info'] = '已结束';
                    }
                }

                // 教学点级别名称
                if (isset($class['ocation_level']) && method_exists($this, 'getLevelName')) {
                    $todayClasses[$key]['ocation_level_name'] = $this->getLevelName($class['ocation_level']);
                } else {
                    $todayClasses[$key]['ocation_level_name'] = '未知级别';
                }

                // 处理图片URL
                if (isset($class['course_image']) && method_exists($this, 'getFullImageUrl')) {
                    $todayClasses[$key]['course_image_url'] = $class['course_image'] ? $this->getFullImageUrl($class['course_image']) : '';
                } else {
                    $todayClasses[$key]['course_image_url'] = '';
                }

                // 是否为主教学点的课程
                if (isset($class['ocation_id'])) {
                    $todayClasses[$key]['is_main_ocation'] = $class['ocation_id'] == $ocation_id;
                } else {
                    $todayClasses[$key]['is_main_ocation'] = false;
                }
            }

            return $todayClasses;

        } catch (\Exception $e) {
            return [];
        }
    }

    /**
     * 获取教学点及其所有子教学点的ID
     * @param int|array $ocation_ids 教学点ID或ID数组
     * @return array
     */
    private function getAllSubOcationIds($ocation_ids)
    {
        try {
            $ocationIds = [];
            $visitedIds = []; // 跟踪已访问的ID，防止循环引用
            $maxDepth = 10; // 最大递归深度
            $maxCount = 1000; // 最大处理数量

            // 检查参数是否有效
            if (empty($ocation_ids)) {
                return [];
            }

            if (is_array($ocation_ids)) {
                // 处理数组情况：遍历所有教学点ID
                foreach ($ocation_ids as $ocation_id) {
                    if ($ocation_id && is_numeric($ocation_id)) {
                        $ocationIds[] = (int)$ocation_id; // 添加主教学点ID
                        $this->getSubOcationIdsRecursive($ocation_id, $ocationIds, $visitedIds, 0, $maxDepth, $maxCount);
                    }
                }
            } else {
                // 处理单个ID情况
                if ($ocation_ids && is_numeric($ocation_ids)) {
                    $ocationIds = [(int)$ocation_ids]; // 添加主教学点ID
                    $this->getSubOcationIdsRecursive($ocation_ids, $ocationIds, $visitedIds, 0, $maxDepth, $maxCount);
                }
            }

            return array_unique($ocationIds);

        } catch (\Exception $e) {
            // 异常时返回原始输入（确保至少有主教学点ID）
            if (is_array($ocation_ids)) {
                return array_filter($ocation_ids, function ($id) {
                    return $id && is_numeric($id);
                });
            } else {
                return ($ocation_ids && is_numeric($ocation_ids)) ? [(int)$ocation_ids] : [];
            }
        }
    }

    /**
     * 递归获取子教学点ID
     * @param int $parent_id 父级教学点ID
     * @param array &$ocationIds 教学点ID数组（引用传递）
     * @param array &$visitedIds 已访问的ID数组（引用传递，防止循环引用）
     * @param int $currentDepth 当前递归深度
     * @param int $maxDepth 最大递归深度
     * @param int $maxCount 最大处理数量
     */
    private function getSubOcationIdsRecursive($parent_id, &$ocationIds, &$visitedIds, $currentDepth = 0, $maxDepth = 10, $maxCount = 1000)
    {
        try {
            // 检查参数是否有效
            if (!is_numeric($parent_id) || $parent_id <= 0) {
                return;
            }

            // 防止死循环的检查
            if (in_array($parent_id, $visitedIds)) {
                return; // 已经访问过此ID，避免循环引用
            }

            // 检查递归深度
            if ($currentDepth >= $maxDepth) {
                return; // 达到最大递归深度，停止递归
            }

            // 检查处理数量
            if (count($ocationIds) >= $maxCount) {
                return; // 达到最大处理数量，停止处理
            }

            // 标记当前ID为已访问
            $visitedIds[] = $parent_id;

            $subOcations = Db::name('ocation')
                ->where('pid', $parent_id)
                ->where('status', 1)
                ->column('id');

            if (is_array($subOcations) && !empty($subOcations)) {
                foreach ($subOcations as $subId) {
                    if (is_numeric($subId) && $subId > 0) {
                        $ocationIds[] = (int)$subId;
                        // 递归获取子级的子级
                        $this->getSubOcationIdsRecursive($subId, $ocationIds, $visitedIds, $currentDepth + 1, $maxDepth, $maxCount);
                    }
                }
            }

        } catch (\Exception $e) {
            // 忽略错误，继续处理
        }
    }

    /**
     * 更新fa_ocation表中community_id为空或为0的记录
     */
    private function updateOcationCommunityIds()
    {
        try {
            // 查找community_id为空或为0的教学点
            $emptyOcations = Db::name('ocation')
                ->where(function ($query) {
                    $query->whereNull('community_id')
                        ->whereOr('community_id', 0)
                        ->whereOr('community_id', '');
                })
                ->where('status', 1)
                ->field('id')
                ->select();

            if (empty($emptyOcations)) {
                return;
            }

            $updateCount = 0;
            foreach ($emptyOcations as $ocation) {
                $ocation_id = $ocation['id'];

                // 使用Community控制器的findCommunityId方法查找community_id
                $community_id = $this->findCommunityId($ocation_id);

                if ($community_id) {
                    // 更新fa_ocation表中的community_id字段
                    $result = Db::name('ocation')
                        ->where('id', $ocation_id)
                        ->update([
                            'community_id' => $community_id,
                        ]);

                    if ($result) {
                        $updateCount++;
                    }
                }
            }

            // 记录更新日志
            if ($updateCount > 0) {
                \think\Log::record("更新了 {$updateCount} 个教学点的community_id字段", 'info');
            }

        } catch (\Exception $e) {
            \think\Log::record("更新教学点community_id失败: " . $e->getMessage(), 'error');
        }
    }

    /**
     * 根据ocation_id查找对应的community_id
     * 复制自Community控制器的findCommunityId方法
     * @param int $ocation_id 教学点ID
     * @return int|null 社区ID
     */
    private function findCommunityId($ocation_id)
    {
        try {
            // 检查参数是否有效
            if (!is_numeric($ocation_id) || $ocation_id <= 0) {
                return null;
            }

            // 先直接查询eb_school_community表
            $community_id = Db::name('eb_school_community')
                ->where('ocation_id', $ocation_id)
                ->value('community_id');

            if ($community_id && is_numeric($community_id)) {
                return (int)$community_id;
            }

            // 如果没有直接记录，通过父级教学点递归查找
            return $this->findCommunityIdRecursive($ocation_id);

        } catch (\Exception $e) {
            \think\Log::record("查找community_id失败: " . $e->getMessage(), 'error');
            return null;
        }
    }

    /**
     * 递归查找父级教学点的community_id
     * @param int $ocation_id 教学点ID
     * @param int $depth 递归深度
     * @return int|null 社区ID
     */
    private function findCommunityIdRecursive($ocation_id, $depth = 0)
    {
        try {
            // 防止无限递归，最多查找8层
            if ($depth > 8 || empty($ocation_id) || !is_numeric($ocation_id) || $ocation_id <= 0) {
                return null;
            }

            // 查询当前教学点的父级ID
            $parent_id = Db::name('ocation')
                ->where('id', $ocation_id)
                ->value('pid');

            if (!$parent_id || !is_numeric($parent_id) || $parent_id <= 0) {
                return null;
            }

            // 查询父级教学点是否有对应的社区ID
            $community_id = Db::name('eb_school_community')
                ->where('ocation_id', $parent_id)
                ->value('community_id');

            if ($community_id && is_numeric($community_id)) {
                return (int)$community_id;
            }

            // 如果父级也没有，继续向上查找
            return $this->findCommunityIdRecursive($parent_id, $depth + 1);

        } catch (\Exception $e) {
            \think\Log::record("递归查找community_id失败: " . $e->getMessage(), 'error');
            return null;
        }
    }

    public function isCollected($ocation_id, $collect_type = 0)
    {
        // 检查参数是否有效
        if (!is_numeric($ocation_id) || $ocation_id <= 0 || !is_numeric($collect_type)) {
            return false;
        }

        $user = $this->auth->getUser(true);
        if (!$user) {
            return false;
        }

        // 检查用户ID是否存在且有效
        if (!isset($user['uid']) || !is_numeric($user['uid']) || $user['uid'] <= 0) {
            return false;
        }

        $user_id = $user['uid'];

        try {
            $result = Db::name('favorites')
                ->where([
                    'user_id' => $user_id,
                    'type' => $collect_type,
                    'target_id' => $ocation_id,
                    'delete_time' => null
                ])
                ->find();

            return !empty($result);
        } catch (\Exception $e) {
            // 记录错误日志
            \think\Log::record("检查收藏状态失败: " . $e->getMessage(), 'error');
            return false;
        }
    }

    /**
     * 获取事件详情列表（学校/教学点）
     * 支持获取学校列表和根据学校ID获取教学点列表
     *
     * @return \think\Response
     */
    public function list()
    {
        try {
            // 获取请求参数
            $type = $this->request->get('type', ''); // school: 学校, ocation: 教学点
            $school_id = $this->request->get('school_id', 0, 'intval'); // 学校ID（获取教学点时使用）
            $page = $this->request->get('page', 1, 'intval');
            $limit = $this->request->get('limit', 20, 'intval');
            $keyword = $this->request->get('keyword', '', 'trim'); // 搜索关键词

            // 参数验证
            if (empty($type)) {
                return $this->error('type参数不能为空', [], 400);
            }

            // 分页参数验证
            if ($page < 1) $page = 1;
            if ($limit < 1 || $limit > 100) $limit = 20;

            $offset = ($page - 1) * $limit;

            if ($type === 'school') {
                // 获取学校列表
                return $this->getSchoolList($keyword, $limit, $offset);

            } else if ($type === 'ocation') {
                // 获取教学点列表
                if ($school_id <= 0) {
                    return $this->error('获取教学点时school_id参数不能为空', [], 400);
                }
                return $this->getOcationList($school_id, $keyword, $limit, $offset);
            } else if ($type == "second_level_management") {
                return $this->getSecondLevelManagementList($keyword, $limit, $offset);
            } else if ($type == "first_level_management") {
                return $this->getFirstLevelManagementList($keyword, $limit, $offset);
            } else if ($type == "subject_lv") {
                return $this->getSubjectLvIdList($keyword, $limit, $offset);
            } else if ($type == "classes") {
                return $this->getClassesList($keyword, $limit, $offset);
            } else if ($type == "classes_type") {
                return $this->getClassesTypeList($keyword, $limit, $offset);
            } else if ($type == "registereClass") {
                // 请完善查询已报班级的接口getregistereClassList
                return $this->getregistereClassList($keyword, $limit, $offset);
            } else if ($type == "yuyueClass") {
                // 请完善查询已预约班级的接口getYuyueClassList
                return $this->getYuyueClassList($keyword, $limit, $offset);
            }

        } catch (\Exception $e) {
            // 记录错误日志
            \think\Log::record("EventDetails/list接口异常: " . $e->getMessage(), 'error');
            return $this->error('服务器内部错误：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取学校列表
     *
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    public function getSchoolList($keyword = '', $limit = 20, $offset = 0)
    {
        try {
            $query = Db::name('eb_school')
                ->field('id, name, school_logo, thumbnail, address, status, create_time')
                ->where('status', 1); // 只获取启用的学校

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where('name', 'like', "%{$keyword}%");
            }

            // 获取总数
            $total = $query->count();

            // 获取列表数据
            $schools = $query->order('id desc')
                ->limit($offset, $limit)
                ->select();

            // 处理图片URL
            foreach ($schools as $key => $school) {
                $schools[$key]['logo'] = $school['school_logo'] ? getImg($school['school_logo'], 124, 124) : '';
                $schools[$key]['thumbnail'] = $school['thumbnail'] ? getImg($school['thumbnail'], 124, 124) : '';

                // 格式化时间
                if (is_numeric($school['create_time']) && $school['create_time'] > 0) {
                    $schools[$key]['create_time'] = date('Y-m-d H:i:s', $school['create_time']);
                } else {
                    $schools[$key]['create_time'] = $school['create_time'] ? $school['create_time'] : '';
                }
            }

            // 返回前端期望的格式
            $result = [
                'code' => 200,
                'msg' => '获取学校列表成功',
                'data' => [
                    'list' => $schools,
                    'total' => $total,
                    'page' => intval($offset / $limit) + 1,
                    'limit' => $limit,
                    'pages' => ceil($total / $limit)
                ]
            ];
            return json($result);

        } catch (\Exception $e) {
            \think\Log::record("获取学校列表失败: " . $e->getMessage(), 'error');
            return $this->error('获取学校列表失败：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取教学点列表
     *
     * @param int $school_id 学校ID
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    public function getOcationList($school_id, $keyword = '', $limit = 20, $offset = 0)
    {
        try {
            // 首先验证学校是否存在
            $school = Db::name('eb_school')
                ->where('id', $school_id)
                ->where('status', 1)
                ->find();

            if (!$school) {
                return $this->error('指定的学校不存在或已被禁用', [], 404);
            }

            // 构建教学点查询
            $query = Db::name('fa_ocation')
                ->alias('o')
                ->join('fa_ocation o2', 'o.pid = o2.id', 'LEFT')
                ->field('
                    o.id, 
                    o.name, 
                    o.address, 
                    o.longitude, 
                    o.latitude, 
                    o.cover,
                    o.status,
                    o.address_lv_octionlevel as level,
                    o.create_time,
                    o2.name as parent_name,
                    CASE 
                        WHEN o.address_lv_octionlevel = 1 THEN "一级教学点"
                        WHEN o.address_lv_octionlevel = 2 THEN "二级教学点"
                        WHEN o.address_lv_octionlevel = 3 THEN "三级教学点"
                        ELSE "未知级别"
                    END as level_name
                ')
                ->where('o.status', 1) // 只获取启用的教学点
                ->where('o.rel_type', 1) // 关联类型为学校
                ->where('o.rel_id', $school_id); // 关联的学校ID

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('o.name', 'like', "%{$keyword}%")
                        ->whereOr('o.address', 'like', "%{$keyword}%");
                });
            }

            // 获取总数 - 克隆查询对象避免影响后续查询
            $countQuery = clone $query;
            $total = $countQuery->count();

            // 获取列表数据
            $ocations = $query->order('o.address_lv_octionlevel asc, o.weigh desc, o.id desc')
                ->limit($offset, $limit)
                ->select();

            // 处理数据
            foreach ($ocations as $key => $ocation) {
                // 处理图片URL
                $ocations[$key]['cover'] = $ocation['cover'] ? getImg($ocation['cover'], 200, 200) : '';

                // 处理坐标
                $ocations[$key]['longitude'] = $ocation['longitude'] ? (float)$ocation['longitude'] : 0.0;
                $ocations[$key]['latitude'] = $ocation['latitude'] ? (float)$ocation['latitude'] : 0.0;

                // 格式化时间
                if (is_numeric($ocation['create_time']) && $ocation['create_time'] > 0) {
                    $ocations[$key]['create_time'] = date('Y-m-d H:i:s', $ocation['create_time']);
                } else {
                    $ocations[$key]['create_time'] = $ocation['create_time'] ? (string)$ocation['create_time'] : '';
                }

                // 处理教学点名称（确保以"教学点"结尾）
                $ocations[$key]['name'] = preg_replace("/教学点$/U", "", $ocation['name']) . "教学点";

                // 添加学校信息
                $ocations[$key]['school_id'] = $school_id;
                $ocations[$key]['school_name'] = $school['name'];
            }

            // 返回前端期望的格式
            $result = [
                'code' => 200,
                'msg' => '获取教学点列表成功',
                'data' => [
                    'list' => $ocations,
                    'total' => $total,
                    'page' => intval($offset / $limit) + 1,
                    'limit' => $limit,
                    'pages' => ceil($total / $limit)
                ]
            ];
            return json($result);

        } catch (\Exception $e) {
            \think\Log::record("获取教学点列表失败: " . $e->getMessage(), 'error');
            return $this->error('获取教学点列表失败：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取二级管理列表
     *
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    private function getSecondLevelManagementList($keyword = '', $limit = 20, $offset = 0)
    {
        try {
            // 获取二级教学点列表（address_lv_octionlevel = 2）
            $query = Db::name('fa_ocation')
                ->alias('o')
                ->join('fa_ocation o2', 'o.pid = o2.id', 'LEFT')
                ->join('fa_ocation o3', 'o2.pid = o3.id', 'LEFT')
                ->field('
                    o.id, 
                    o.name, 
                    o.address, 
                    o.longitude, 
                    o.latitude, 
                    o.cover,
                    o.status,
                    o.create_time,
                    o2.name as parent_name,
                    o3.name as root_name
                ')
                ->where('o.status', 1) // 只获取启用的教学点
                ->where('o.address_lv_octionlevel', 2); // 二级教学点

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('o.name', 'like', "%{$keyword}%")
                        ->whereOr('o.address', 'like', "%{$keyword}%");
                });
            }

            // 获取总数
            $countQuery = clone $query;
            $total = $countQuery->count();

            // 获取列表数据
            $ocations = $query->order('o.weigh desc, o.id desc')
                ->limit($offset, $limit)
                ->select();

            // 处理数据
            foreach ($ocations as $key => $ocation) {
                // 处理图片URL
                $ocations[$key]['cover'] = $ocation['cover'] ? getImg($ocation['cover'], 200, 200) : '';

                // 处理坐标
                $ocations[$key]['longitude'] = $ocation['longitude'] ? (float)$ocation['longitude'] : 0.0;
                $ocations[$key]['latitude'] = $ocation['latitude'] ? (float)$ocation['latitude'] : 0.0;

                // 格式化时间
                if (is_numeric($ocation['create_time']) && $ocation['create_time'] > 0) {
                    $ocations[$key]['create_time'] = date('Y-m-d H:i:s', $ocation['create_time']);
                } else {
                    $ocations[$key]['create_time'] = $ocation['create_time'] ? (string)$ocation['create_time'] : '';
                }

                // 处理教学点名称（确保以"教学点"结尾）
                $ocations[$key]['name'] = preg_replace("/教学点$/U", "", $ocation['name']) . "教学点";
            }

            return $this->success('获取二级管理列表成功', [
                'list' => $ocations,
                'total' => $total,
                'page' => intval($offset / $limit) + 1,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]);

        } catch (\Exception $e) {
            \think\Log::record("获取二级管理列表失败: " . $e->getMessage(), 'error');
            return $this->error('获取二级管理列表失败：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取一级管理列表
     *
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    private function getFirstLevelManagementList($keyword = '', $limit = 20, $offset = 0)
    {
        try {
            // 获取一级教学点列表（address_lv_octionlevel = 1）
            $query = Db::name('fa_ocation')
                ->alias('o')
                ->field('
                    o.id, 
                    o.name, 
                    o.address, 
                    o.longitude, 
                    o.latitude, 
                    o.cover,
                    o.status,
                    o.create_time,
                    o.rel_type,
                    o.rel_id
                ')
                ->where('o.status', 1) // 只获取启用的教学点
                ->where('o.address_lv_octionlevel', 1); // 一级教学点

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('o.name', 'like', "%{$keyword}%")
                        ->whereOr('o.address', 'like', "%{$keyword}%");
                });
            }

            // 获取总数
            $countQuery = clone $query;
            $total = $countQuery->count();

            // 获取列表数据
            $ocations = $query->order('o.weigh desc, o.id desc')
                ->limit($offset, $limit)
                ->select();

            // 处理数据
            foreach ($ocations as $key => $ocation) {
                // 处理图片URL
                $ocations[$key]['cover'] = $ocation['cover'] ? getImg($ocation['cover'], 200, 200) : '';

                // 处理坐标
                $ocations[$key]['longitude'] = $ocation['longitude'] ? (float)$ocation['longitude'] : 0.0;
                $ocations[$key]['latitude'] = $ocation['latitude'] ? (float)$ocation['latitude'] : 0.0;

                // 格式化时间
                if (is_numeric($ocation['create_time']) && $ocation['create_time'] > 0) {
                    $ocations[$key]['create_time'] = date('Y-m-d H:i:s', $ocation['create_time']);
                } else {
                    $ocations[$key]['create_time'] = $ocation['create_time'] ? (string)$ocation['create_time'] : '';
                }

                // 处理教学点名称（确保以"教学点"结尾）
                $ocations[$key]['name'] = preg_replace("/教学点$/U", "", $ocation['name']) . "教学点";

                // 获取关联的学校或社区信息
                if ($ocation['rel_type'] == 1) {
                    // 关联学校
                    $school = Db::name('eb_school')
                        ->where('id', $ocation['rel_id'])
                        ->field('id, name')
                        ->find();
                    $ocations[$key]['rel_name'] = $school ? $school['name'] : '';
                    $ocations[$key]['rel_type_name'] = '学校';
                } else if ($ocation['rel_type'] == 2) {
                    // 关联社区
                    $community = Db::name('fa_community')
                        ->where('id', $ocation['rel_id'])
                        ->field('id, name')
                        ->find();
                    $ocations[$key]['rel_name'] = $community ? $community['name'] : '';
                    $ocations[$key]['rel_type_name'] = '社区';
                } else {
                    $ocations[$key]['rel_name'] = '';
                    $ocations[$key]['rel_type_name'] = '未知';
                }
            }

            return $this->success('获取一级管理列表成功', [
                'list' => $ocations,
                'total' => $total,
                'page' => intval($offset / $limit) + 1,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]);

        } catch (\Exception $e) {
            \think\Log::record("获取一级管理列表失败: " . $e->getMessage(), 'error');
            return $this->error('获取一级管理列表失败：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取学科级别列表
     *
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    public function getSubjectLvIdList($keyword = '', $limit = 20, $offset = 0)
    {
        try {
            // 获取学科级别列表
            $query = Db::name('fa_subject_lv')
                ->alias('s')
                ->join('fa_course_type s2', 's.course_type_id = s2.id', 'left')
                ->field('
                    s.id, 
                    s.name, 
                    s.pid,
                    s.status,
                    s2.name as parent_name
                ')
                ->where('s.status', 1)->where('s.level', 3); // 只获取启用的学科级别

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('s.name', 'like', "%{$keyword}%")
                        ->whereOr('s2.name', 'like', "%{$keyword}%");
                });
            }

            // 获取总数
            $countQuery = clone $query;
            $total = $countQuery->count();

            // 获取列表数据
            $subjects = $query->order('s.pid asc, s.weigh desc, s.id desc')
                ->limit($offset, $limit)
                ->select();

            // 处理数据
            foreach ($subjects as $key => $subject) {

                // 添加级别信息
                if ($subject['pid'] == 0) {
                    $subjects[$key]['level'] = 1;
                    $subjects[$key]['level_name'] = '一级学科';
                } else {
                    $subjects[$key]['level'] = 2;
                    $subjects[$key]['level_name'] = '二级学科';
                }
            }

            return $this->success('获取学科级别列表成功', [
                'list' => $subjects,
                'total' => $total,
                'page' => intval($offset / $limit) + 1,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]);

        } catch (\Exception $e) {
            \think\Log::record("获取学科级别列表失败: " . $e->getMessage(), 'error');
            return $this->error('获取学科级别列表失败：' . $e->getMessage(), [], 500);
        }
    }

    public function getClassesTypeList($keyword, $limit, $offset)
    {
        return $this->success('获取班级类型列表成功', [
            'list' => [
                ['id' => 1, 'name' => '学校班级'],
                ['id' => 2, 'name' => '社区班级']
            ]
        ]);
    }

    public function getregistereClassList($keyword, $limit, $offset)
    {
        try {
            $user = $this->auth->getUser();
            $userId = $user['uid'];

            // 获取排序参数
            $sort = $this->request->get('sort', '');
            $sortField = 'o.update_time'; // 默认排序字段
            $sortOrder = 'desc'; // 默认排序顺序

            // 如果有sort参数，解析排序字段和顺序
            if (!empty($sort)) {
                $lastUnderscorePos = strrpos($sort, '_');
                if ($lastUnderscorePos !== false) {
                    $sortField = substr($sort, 0, $lastUnderscorePos);
                    $sortOrder = substr($sort, $lastUnderscorePos + 1);
                    $sortField = ($sortField == "register_time") ? "o.create_time" : $sortField;
                    $sortField = ($sortField == "class_time") ? "start_date" : $sortField;
                    // 验证排序顺序
                    if (!in_array(strtolower($sortOrder), ['asc', 'desc'])) {
                        $sortOrder = 'desc';
                    }
                }
            }

            // 查询已报班级信息
            $query = Db::name('eb_apply_form_item')
                ->alias("f")
                ->join("fa_order o", "f.order_id = o.id", "left")
                ->join("eb_classes c", "f.classes_type=1 and f.classes_id = c.id", "left")
                ->join("fa_ocation_class c2", "f.classes_type=2 and f.classes_id = c2.id", "left")
                ->join("fa_subject_lv c3", "f.classes_type=1 and c.subject_lv = c3.id", "left")
                ->join("fa_community_course_config c4", "f.classes_type=2 and c2.subject_lv = c4.id", "left")
                ->join("fa_ocation loc", "loc.id = c.ocation_id", "left")
                ->join("fa_ocation loc2", "loc2.id = c2.ocation_id", "left")
                ->join("fa_course_table_autoplan a", "c.id=a.classes_id and c.classes_type=1", "left")
                ->join("fa_course_table_autoplan a2", "c2.id=a2.classes_id and c2.classes_type=2 and c2.subject_lv=a2.subject_lv", "left")
                ->where("f.user_id", $userId)
                ->where("o.pay_status", 1);


            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('c.name', 'like', "%{$keyword}%")
                        ->whereOr('c2.name', 'like', "%{$keyword}%")
                        ->whereOr('loc.address', 'like', "%{$keyword}%")
                        ->whereOr('c3.name', 'like', "%{$keyword}%");
                });
            }

            // 获取总数
            $countQuery = clone $query;
            $total = $countQuery->group("o.order_sn, f.classes_id")->count();

            // 获取列表数据
            $classList = $query->field("
                    f.id as apply_item_id,
                    f.pay_status as apply_item_pay_status,
                    o.refund_status,
                    f.*,
                    c.ocation_id as c_ocation_id,
                    loc.id as ocation_id,
                    o.order_sn,
                    o.out_trade_no,
                    c.name as class_name,
                    loc.address as address,
                    COALESCE(c2.subject_lv, c.subject_lv) as subjectlv_id,
                    COALESCE(c2.name, c.name) as class_name,
                    COALESCE(c3.name, c4.name) AS subject_name,
                    COALESCE(c2.school_id, c.school_id) AS school_id,
                    date(a.date) as start_date,
                    o.amount as amount,
                    o.payment_status,
                    o.pay_time,
                    o.pay_type,
                    o.pay_channel_id
                ")
                ->where("o.pay_status", 1)
                ->group("c.id")
                ->order($sortField . ' ' . $sortOrder . ', f.update_time desc')
                ->limit($offset, $limit)
                ->select();

            if (!$classList) {
                return $this->error('没有已报班级信息');
            }

            // 格式化数据
            foreach ($classList as &$item) {
                $item['title'] = model("\app\common\model\Classes")->getClasses_idTextAttr($item['classes_id'], $item);
                $item['school_name'] = model("\app\admin\model\School")->getSchool_idTextAttr($item['school_id'], $item);
                $item['pay_status'] = $item['pay_status'] == 1 ? '已支付' : ($item['pay_status'] == 4 ? '已退费' : '待支付');
                $item['payment_status'] = $item['payment_status'] == 1 ? '已支付' : '待支付';
                $item['pay_time'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '';

                // 添加最新的更新时间，用于前端排序
                $item['update_time'] = max(
                    $item['update_time'] ?? 0,
                    $item['pay_time'] ? strtotime($item['pay_time']) : 0
                );
            }

            $groupsMap = [];
            foreach ($classList as $it) {
                $sn = isset($it['school_name']) && $it['school_name'] ? $it['school_name'] : '未知学校';
                $sid = isset($it['school_id']) ? $it['school_id'] : 0;
                if (!isset($groupsMap[$sn])) {
                    $groupsMap[$sn] = [
                        'school_id' => $sid,
                        'school_name' => $sn,
                        'count' => 0,
                        'latest_update_time' => 0,
                        'courses' => []
                    ];
                }
                $groupsMap[$sn]['courses'][] = $it;
                $groupsMap[$sn]['count'] += 1;
                $groupsMap[$sn]['latest_update_time'] = max($groupsMap[$sn]['latest_update_time'], $it['update_time']);
            }
            $groups = array_values($groupsMap);
            usort($groups, function ($a, $b) {
                return $b['latest_update_time'] <=> $a['latest_update_time'];
            });

            return $this->success('获取已报班级成功', [
                'list' => $classList,
                'groups' => $groups,
                'group_total' => count($groups),
                'total' => $total,
                'page' => intval($offset / $limit) + 1,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]);

        } catch (\Exception $e) {
            \think\Log::record("获取已报班级失败: " . $e->getMessage(), 'error');
            return $this->error('获取已报班级失败：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取已预约班级列表
     *
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    public function getYuyueClassList($keyword, $limit, $offset)
    {
        try {
            $user = $this->auth->getUser();
            $userId = $user['uid'];

            // 查询已预约班级信息（classes_type=2的社区课程）
            $query = Db::name('eb_apply_form_item')
                ->alias("f")
                ->join("fa_order o", "f.order_id = o.id", "left")
                ->join("eb_classes c", "f.classes_type=1 and f.classes_id = c.id", "left")
                ->join("fa_ocation_class c2", "f.classes_type=2 and f.classes_id = c2.id", "left")
                ->join("fa_community_course_config c3", "c2.subject_lv = c3.id", "left")
                ->join("fa_ocation loc", "loc.id = c.ocation_id", "left")
                ->join("fa_ocation loc2", "loc2.id = c2.ocation_id", "left")
                ->join("fa_course_table_autoplan a", "c.id=a.classes_id and c.classes_type=1", "left")
                ->join("fa_course_table_autoplan a2", "c2.id=a2.classes_id and c2.classes_type=2 and c2.subject_lv=a2.subject_lv", "left")
                ->join("fa_community_code_config cm", "c2.community_id = cm.id", "left")
                ->join("fa_community_publicwelfare pw", "c2.publicwelfare_id = pw.id", "left")
                ->where("f.user_id", $userId)
                ->where("f.classes_type", 2) // 只查询社区课程（预约课程）
                ->where(function ($query) {
                    $query->where("f.status", 1)->whereOr("f.pay_status", 4);
                });

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('c2.name', 'like', "%{$keyword}%")
                        ->whereOr('loc2.address', 'like', "%{$keyword}%")
                        ->whereOr('c3.name', 'like', "%{$keyword}%")
                        ->whereOr('cm.name', 'like', "%{$keyword}%")
                        ->whereOr('pw.project_name', 'like', "%{$keyword}%");
                });
            }

            // 获取总数
            $countQuery = clone $query;
            $total = $countQuery->group("o.order_sn, f.classes_id")->count();

            // 获取列表数据
            $classList = $query->field("
                    f.id as apply_item_id,
                    f.pay_status as apply_item_pay_status,
                    o.refund_status,
                    f.*,
                    c2.ocation_id as c_ocation_id,
                    loc2.id as ocation_id,
                    o.order_sn,
                    o.out_trade_no,
                    c2.name as class_name,
                    loc2.address as address,
                    c3.name as subject_name,
                    date(a2.date) as start_date,
                    cm.name as community_name,
                    pw.project_name as publicwelfare_name,
                    o.amount as amount,
                    o.payment_status,
                    o.pay_time,
                    o.pay_type,
                    o.pay_channel_id
                ")
                ->group("o.order_sn, f.classes_id")
                ->order("o.update_time desc, f.update_time desc")
                ->limit($offset, $limit)
                ->select();

            if (!$classList) {
                return $this->error('没有已预约班级信息');
            }

            // 格式化数据
            foreach ($classList as &$item) {
                $item['title'] = $item['class_name'];
                $item['community_name'] = $item['community_name'] ?? '';
                $item['publicwelfare_name'] = $item['publicwelfare_name'] ?? '';
                $item['pay_status'] = $item['pay_status'] == 1 ? '已支付' : ($item['pay_status'] == 4 ? '已退费' : '待支付');
                $item['payment_status'] = $item['payment_status'] == 1 ? '已支付' : '待支付';
                $item['pay_time'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '';
                $item['create_time'] = substr($item['create_time'], 0, 10);
                // 添加最新的更新时间，用于前端排序
                $item['update_time'] = max(
                    $item['update_time'] ?? 0,
                    $item['pay_time'] ? strtotime($item['pay_time']) : 0
                );

                // 标记为预约课程
                $item['is_yuyue'] = 1;
                $item['class_type_name'] = '社区课程(预约)';
            }

            return $this->success('获取已预约班级成功', [
                'list' => $classList,
                'total' => $total,
                'page' => intval($offset / $limit) + 1,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]);

        } catch (\Exception $e) {
            \think\Log::record("获取已预约班级失败: " . $e->getMessage(), 'error');
            return $this->error('获取已预约班级失败：' . $e->getMessage(), [], 500);
        }
    }

    /**
     * 获取班级列表
     *
     * @param string $keyword 搜索关键词
     * @param int $limit 每页数量
     * @param int $offset 偏移量
     * @return \think\Response
     */
    public function getClassesList($keyword = '', $limit = 20, $offset = 0)
    {
        try {
            // 获取班级列表（包括学校班级和社区班级）
            $query = Db::name('eb_classes')
                ->alias('c')
                ->join('fa_school s', 'c.school_id = s.id', 'LEFT')
                ->join('fa_community cm', 'c.community_id = cm.id', 'LEFT')
                ->join('fa_ocation o', 'c.ocation_id = o.id', 'LEFT')
                ->join('fa_subject_lv sub', 'c.subject_lv = sub.id', 'LEFT')
                ->field('
                    c.id, 
                    c.name, 
                    c.school_id,
                    c.community_id,
                    c.ocation_id,
                    c.subject_lv,
                    c.classes_type,
                    c.cover,
                    c.num,
                    c.intro,
                    c.status,
                    c.create_time,
                    s.name as school_name,
                    cm.name as community_name,
                    o.name as ocation_name,
                    sub.name as subject_name,
                    CASE 
                        WHEN c.classes_type = 1 THEN "学校班级"
                        WHEN c.classes_type = 2 THEN "社区班级"
                        ELSE "未知类型"
                    END as classes_type_name
                ')
                ->where('c.status', 1); // 只获取启用的班级

            // 关键词搜索
            if (!empty($keyword)) {
                $query->where(function ($query) use ($keyword) {
                    $query->whereOr('c.name', 'like', "%{$keyword}%")
                        ->whereOr('s.name', 'like', "%{$keyword}%")
                        ->whereOr('cm.name', 'like', "%{$keyword}%")
                        ->whereOr('o.name', 'like', "%{$keyword}%")
                        ->whereOr('sub.name', 'like', "%{$keyword}%");
                });
            }

            // 获取总数
            $countQuery = clone $query;
            $total = $countQuery->count();

            // 获取列表数据
            $classes = $query->order('c.classes_type asc, c.id desc')
                ->limit($offset, $limit)
                ->select();

            // 处理数据
            foreach ($classes as $key => $class) {
                // 处理图片URL
                $classes[$key]['cover'] = $class['cover'] ? getImg($class['cover'], 200, 200) : '';

                // 格式化时间
                if (is_numeric($class['create_time']) && $class['create_time'] > 0) {
                    $classes[$key]['create_time'] = date('Y-m-d H:i:s', $class['create_time']);
                } else {
                    $classes[$key]['create_time'] = $class['create_time'] ? (string)$class['create_time'] : '';
                }

                // 获取报名人数
                $applyCount = Db::name('eb_apply_form_item')
                    ->where('classes_id', $class['id'])
                    ->where('status', 1)
                    ->count();
                $classes[$key]['apply_count'] = $applyCount;

                // 计算剩余名额
                $classes[$key]['remaining_slots'] = max(0, $class['num'] - $applyCount);
            }

            return $this->success('获取班级列表成功', [
                'list' => $classes,
                'total' => $total,
                'page' => intval($offset / $limit) + 1,
                'limit' => $limit,
                'pages' => ceil($total / $limit)
            ]);

        } catch (\Exception $e) {
            \think\Log::record("获取班级列表失败: " . $e->getMessage(), 'error');
            return $this->error('获取班级列表失败：' . $e->getMessage(), [], 500);
        }
    }

    function weekname($weekday)
    {
        $week = array("日", "一", "二", "三", "四", "五", "六");
        return $week[$weekday];
    }

    function format_content($content)
    {
        // 确保参数不为null，如果是null则转换为空字符串
        if ($content === null || $content === '') {
            return '';
        }
        $processedContent = (string)$content;

        // 首先清理内容，保留基本标签
        $processedContent = strip_tags($processedContent, "<p><br><b><img><h1><h2><h3><h4><h5><h6><strong><b>");
        $processedContent = preg_replace("/<(?!img)([a-zA-Z]+)\s.*>/Uisx", "<\\1>", $processedContent);
        //每一对换行符中间的换行符替换为空格
        $processedContent = preg_replace('/\n+/', ' ', $processedContent);

        // 为p标签添加样式，但排除以一、二、三...等数字开头的段落
        $processedContent = preg_replace_callback(
            '/<p>(.*?)<\/p>/is',
            function ($matches) {
                $pContent = $matches[1];

                // 检查段落内容是否以一、二、三、四、五、六、七、八、九、十等数字开头
                if (preg_match('/^\s*[一二三四五六七八九十]+[、\.\s]/u', $pContent)) {
                    // 数字开头的段落不缩进
                    return '<p style="font-size: 18px; color: #000; line-height: 1.6; margin: 10px 0; line-height: 1.5;">' . $pContent . '</p>';
                } else {
                    // 普通段落缩进2个字符
                    return '<p style="font-size: 18px; color: #000; line-height: 1.6; margin: 10px 0; text-indent: 2em; line-height: 1.5;">' . $pContent . '</p>';
                }
            },
            $processedContent
        );

        // 提取第一行作为标题，通常是第一行
        //第一对<p>标签之间的内容作为标题将其包装为h1标题,且除html处理后的内容不为空
        if (preg_match('/<p[^>]*>(.*?)<\/p>/i', $processedContent, $matches)) {
            $firstLine = trim($matches[1]);
            if ($firstLine && !preg_match('/^\s*<[^>]+>/', $firstLine)) {
                $processedContent = '<h1 style="font-size: 22px; color: #333; font-weight: bold; text-align: center; margin: 20px 0; line-height: 1.5;">' . htmlspecialchars($firstLine) . '</h1>' . "\n" . $processedContent;
            }
        }

        // 在内容头部添加样式表
        $styleTag = '<style>
            p {
                text-indent: 2em !important;
                margin: 10px 0 !important;
                line-height: 1.6 !important;
            }
            h1 {
                font-size: 22px !important;
                color: #333 !important;
                font-weight: bold !important;
                text-align: center !important;
                margin: 20px 0 !important;
                line-height: 1.5 !important;
            }
            h2 {
                font-size: 18px !important;
                color: #000 !important;
                font-weight: bold !important;
                margin: 15px 0 10px !important;
                line-height: 2.5 !important;
            }
        </style>' . "\n";

        // 确保preg_replace返回的是字符串，而不是null
        if ($processedContent === null) {
            $processedContent = (string)$content;
        }

        $processedContent = $processedContent;



        // 使用正则表达式匹配从段落头部开始到h1标签的部分
        $processedContent = preg_replace(
            '/<h1([^>]*)>/im',
            '<h1$2 style="font-size: 22px; color: #333; font-weight: bold; text-align: center; margin-left: -50px;margin-top: 20px;margin-bottom: 20px; line-height: 1.5;">',
            $processedContent
        );



        // 为h2标签添加样式
        $processedContent = preg_replace(
            '/<h2([^>]*)>/i',
            '<h2$1 style="font-size: 18px; color: #000; font-weight: bold; margin: 15px 0 10px; line-height: 2.5;">',
            $processedContent
        );

        return $processedContent;
    }
}